diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 54d3895..f9db99a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: - name: Install Flutter and Dart SDK uses: subosito/flutter-action@v2 with: - channel: "beta" + channel: "stable" - name: Show Dart SDK version run: dart --version diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5bda174..46f0d4d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -35,7 +35,7 @@ jobs: - name: Install Flutter and Dart SDK uses: subosito/flutter-action@v2 with: - channel: "beta" + channel: "stable" - name: Show Dart SDK version run: dart --version diff --git a/.github/workflows/deploy_test.yml b/.github/workflows/deploy_test.yml index d5076a8..8cc971f 100644 --- a/.github/workflows/deploy_test.yml +++ b/.github/workflows/deploy_test.yml @@ -36,7 +36,7 @@ jobs: - name: Install Flutter and Dart SDK uses: subosito/flutter-action@v2 with: - channel: "beta" + channel: "stable" - name: Show Dart SDK version run: dart --version diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c929172..1ed0daf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,7 +29,7 @@ jobs: - name: Install Flutter and Dart SDK uses: subosito/flutter-action@v2 with: - channel: "beta" + channel: "stable" - name: Show Dart SDK version run: dart --version diff --git a/CHANGELOG.md b/CHANGELOG.md index bef9d60..c810ebd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,16 +2,26 @@ All notable changes to the **FlexColorPicker** package are documented in this file. -## 3.5.0-dev.1 +## 3.5.0 -**May 13, 2024** +**May 15, 2024** -Requires min Flutter 3.22.0 and Dart 3.4.0. +Requires min Flutter 3.22.0. No new features or fixes in this release. A version bump to use FlexSeedScheme 2.0.0 compatible with Flutter version 3.22.0 and its new breaking ColorScheme. The ColorPicker contains no breaking changes, but underlying Flutter does and this version is only compatible with Flutter 3.22.0 and later. +**NEW** + +* Added property `mainAxisSize` to `ColorPicker` and `showColorPickerDialog`, it controls the vertical axis size of the picker's column layout. Defaults to `MainAxisSize.max` as before, like `Columns` do by default. The property was added to enable setting the dialog to use `MainAxisSize.min` if needed. + +**FIX** + +* Fix wheel picker jumping to BW or custom picker under certain conditions. + * When the wheel picker's opacity value is not 100, moving the color picker cursor to the white corner or bottom black edge of the color box triggers a jump. It auto-selects BW or a custom picker containing black or white values. This is now fixed. The picker cursor will stay in the wheel picker, and the color box will not jump to BW or custom picker when the cursor is moved to the white corner or bottom black edge of the color box. +* Improved and updated API documentation for `ColorPicker` properties `color` and `onColorChanged`. +* Fixed typos and language in the readme. ## 3.4.1 @@ -22,7 +32,7 @@ The ColorPicker contains no breaking changes, but underlying Flutter does and th Package -- Fixed [#81](https://github.com/rydmike/flex_color_picker/issues/81) The property `tonalSubheading` in the convenience dialog function `showColorPickerDialog` was never passed along to the `ColorPicker` used to construct the dialog, causing the tonal sub heading to never show up in the resulting dialog. +- Fixed [#81](https://github.com/rydmike/flex_color_picker/issues/81) The property `tonalSubheading` in the convenience dialog function `showColorPickerDialog` was never passed along to the `ColorPicker` used to construct the dialog, causing the tonal subheading to never show up in the resulting dialog. **New** diff --git a/README.md b/README.md index bfc9a48..7101c41 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,7 @@ for more information about the Material 3 color system and tonal palettes. The picker is Windows, Mac, Linux and Web desktop compatible. It has desktop focus handling plus optional menus -and buttons for handling COPY-PASTE of colors from and to the picker, including desktop platform -aware COPY-PASTE keyboard shortcuts. +and buttons for handling COPY-PASTE of colors from and to the picker, including desktop platform-aware COPY-PASTE keyboard shortcuts. ColorPicker variations upper @@ -82,14 +81,14 @@ configure the `ColorPicker` to include any of the above color pickers. Showing p is not very useful, they are available as optional ways of showing and selecting the standard Material primary and accent colors. -Give the `ColorPicker` a heading and a subheading for the color shades, typically Text widgets with appropriate style. +Give the `ColorPicker` a heading and a subheading for the color shades, typically Text widgets with an appropriate style. Decide if the Material shades can be selected or not and if the selected color name and RGB code are visible in the picker. If the color HEX RGB code is visible, the picker can also include a button that allows you to copy the selected color code to the clipboard directly from the field. On the wheel picker you can enter a HEX RGB color code, and the wheel picker will move to select the entered color, while also creating a color swatch for it. The shape, size and spacing of the color picker items can be modified. There is a built-in dialog that can be used to -show and use the `ColorPicker` in a dialog. You can of course also make your own dialog and just use the `ColorPicker` +show and use the `ColorPicker` in a dialog. You can also make your own dialog and use the `ColorPicker` widget in your own custom dialog or some other type of overlay. ColorPicker variations lower @@ -132,7 +131,7 @@ The source code for the Web demo, which is a bit more elaborate example than exa the package source code in the "example/lib/demo" folder. The Web demo has a responsive view that expands into maximum four separately scrollable columns. The columns contain -a massive amount of controls that you can use to adjust the color picker's settings. On a 1080p desktop screen, +many controls that you can use to adjust the color picker's settings. On a 1080p desktop screen, you can see most of the settings at the same time as the color picker. With this, you can test the settings and see their impact on the picker as you adjust them. @@ -140,8 +139,8 @@ The Web demo also has tooltips for each setting control. The tooltips show the n current value. With this feature, you can use the web demo as a tool to configure the color picker to a desired style, and find the APIs and values that you used. -The same toggle that is used to turn OFF the tooltips in the color picker also turns OFF -the API tooltips in the demo, in case they get in the way. By default, the tooltips are ON, to show the used API and +The same toggle used to turn OFF the tooltips in the color picker also turns OFF +the API tooltips in the demo, in case they get in the way. By default, the tooltips are ON to show the used API and its current value. The **FlexColorPicker** web demo also persists the settings as you change them. The next time you use it, with the same @@ -240,7 +239,7 @@ the `ColorPicker` with the selected `Color` value. In this example we have also child: Card( elevation: 2, child: ColorPicker( - // Use the screenPickerColor as start color. + // Use the screenPickerColor as start and active color. color: screenPickerColor, // Update the screenPickerColor using the callback. onColorChanged: (Color color) => @@ -269,7 +268,7 @@ This gives us round color pick items, and a round color indicator above the pick ## Dialog ColorPicker Method A common use case for a color picker is to show a color selection widget and allow users to select a new color in -a dialog. The `ColorPicker` comes with a built-in dialog that can be used for this. Alternatively you can just use +a dialog. The `ColorPicker` comes with a built-in dialog that can be used for this. Alternatively you can use the `ColorPicker` widget and include it in your own custom dialog. For the first dialog example, we will show all the built-in picker types, except the combined @@ -282,7 +281,7 @@ to get accent color swatches. We add these color swatches as keys to a `ColorSwatch` **Map**, that we map to our own `String` name values for our custom color swatches. You don't have to use the `ColorTools` functions to create the color swatches from -a color, you can just as well define and use your own custom hand tuned `ColorSwatch` swatches created +a color, you can as well define and use your own custom hand tuned `ColorSwatch` swatches created with `MaterialColor` or `MaterialAccentColor`, as shown in the [custom color swatches](#custom-color-swatches) chapter. The `ColorTools` functions are just convenient helpers that can be used to make Material like primary and accent color swatches from a single color value. @@ -350,6 +349,7 @@ we want this color to be visible and not obscured by the dialog. ), ``` +> [!NOTE] > The above `onSelectFocus` property is used to inform the `ColorIndicator` that we do not want it to keep focus > when we select and click on it in desktop and Web applications. On those platforms it gets focus when we > click on it to open the dialog from it. If it keeps focus while the dialog is open and after the dialog is closed, @@ -377,7 +377,7 @@ happen to have `ColorPickerType.custom: true` enabled, the custom picker will no ```dart Future colorPickerDialog() async { return ColorPicker( - // Use the dialogPickerColor as start color. + // Use the dialogPickerColor as start and active color. color: dialogPickerColor, // Update the dialogPickerColor using the callback. onColorChanged: (Color color) => @@ -446,14 +446,14 @@ happen to have `ColorPickerType.custom: true` enabled, the custom picker will no The above example uses a few more `ColorPicker` properties. It is styled to be more compact and to show the general color name via `showColorName`, as well as the selected color's HEX color code by enabling `showColorCode`. With the color code field, you can also copy the color value to the clipboard using the copy icon button -suffix in the field. With the wheel picker you can also enter a hex color RGB value in the color code field. +suffix in the field. With the wheel picker, you can also enter a hex color RGB value in the color code field. The two wheel color HSV selection indicators will move to the color selection matching the entered HEX RGB value. The above example also uses the `copyPasteBehavior` configuration class `ColorPickerCopyPasteBehavior()` with `longPressMenu` set to true, to activate a long press context COPY-PASTE menu in the picker. Most importantly, the above example uses the `showPickerDialog` method to show the defined `ColorPicker` in a -pre-made dialog. The dialog also needs a build-context, that we pass to it. +pre-made dialog. The dialog also needs a build-context, we pass one to it. The above example also demonstrates in version 3.0.0 new custom `transitionBuilder` and `transitionDuration` usage. This part has not been updated to be included in the screen recording below. Please make your own build of the default example to see it. @@ -462,14 +462,14 @@ auto size to fit the dialog content. Using constraints allows the dialog to keep size changes slightly as you switch between the different color picker types you enabled. It just looks a bit better if the dialog size does not change when you switch picker-type with the type selector. The color-wheel picker in particular will often require more space. The wheel size can be customized as well. It does, -however, become more difficult to use if it is made very small. In this example, it is on purposes on the +however, become more difficult to use if it is made too small. In this example, it is on purpose on the lower side of a still usable size. -The end result of the above setup is a `ListTile` where the trailing color indicator widget can be clicked to +The result of the above setup is a `ListTile` where the trailing color indicator widget can be clicked to open a dialog to select a new color for the trailing `ColorIndicator` color. As the `dialogPickerColor` changes the color in the dialog, the `ColorIndicator`'s color also changes via this -interaction. If the dialog is cancelled, the `ColorIndicator`'s original color is restored. +interaction. If the dialog is canceled, the `ColorIndicator`'s original color is restored. ColorPicker dialog demo @@ -506,7 +506,7 @@ color manipulation we just did. If you do not need the feature that allows you to modify and update colors interactively from the dialog via a callback, you can use a more straight-forward async dialog function API. This function opens the picker -with a pre-selected color and either returns the new selected color when closed with **OK**, or returns the +with a pre-selected color and either returns the selected color when closed with **OK**, or returns the color you opened it with, when closed with **Cancel** action. You can call this `showColorPickerDialog` dialog function directly from e.g., an `onTap` or `onSelect` callback, @@ -588,7 +588,7 @@ ListTile( This dialog picker example also introduces a few more properties that we have not used before. For starters, we gave it a `title` widget instead of a `heading`. The title is more like the title of an `AppBar`. We -also skipped all the sub-heading widgets to make a more compact picker. +also skipped all the subheading widgets to make a more compact picker. We used the `copyPasteBehavior` to define a `ColorPickerCopyPasteBehavior` configuration that enables both copy (`copyButton: true`) and paste (`pasteButton: true`) action icon buttons in the picker's top @@ -624,8 +624,8 @@ including its `showPickerDialog` method's parameters, and an `AlertDialog`, with the `showDialog` function and its parameters, all into one large function. Despite its large API surface, it is still rather convenient to use. You seldom need to use -most of the underlying API properties, usually the default values for them work fine. They are however -exposed to the degree they can be, should you ever need them. +most of the underlying API properties, usually the default values for them work fine. They are exposed, +should you ever need them. **Finally**, the default example also includes a light and dark theme mode toggle. It is there so that you can test the look and operation of the color picker with a dark theme. @@ -670,7 +670,7 @@ ColorPicker( ), ``` -If you need to update the `ColorPicker` externally, just pass in a new value to the `color` property. +If you need to update the `ColorPicker` externally pass in a new value to the `color` property. In the above example you could give the state variable `myColor` a new value from some other place than the above `onColorChanged` callback, and call `setState`. The [live Web demo](https://rydmike.com/flexcolorpicker/) includes an example of how you can update the `ColorPicker` via other widget interactions, @@ -704,8 +704,8 @@ picker. Since more than one picker is enabled, the color picker selector automat If you want to show both Material primary and accent colors in the same picker, you can enable the `ColorPickerType.both` picker. In that case you usually want to disable `ColorPickerType.primary` and `ColorPickerType.accent`, as they contain duplicates of already available colors in the `both` picker. The live -Web demo implements this as exclusive selections in its own logic. It is, of course, possible to show all three pickers, -but it does not really make much sense. +Web demo implements this as exclusive selections in its own logic. It is possible to show all three pickers, +but it really makes little sense. ### Enable Shades Selection @@ -715,7 +715,7 @@ By default, selection of the Material primary and Accent **color swatch shade co color, is **enabled**. In the above example `enableShadesSelection` had on purpose been disabled to produce the above, main only color, very compact color picker example. -Below we enable the Material color swatch shades selection. Typically, you want to be able +Below, we enable the Material color swatch shades selection. Typically, you want to be able to also select the Material shade colors. Normally, you would just keep the default enabled setting and don't have to use this property at all. You only need this property if you ant to disable the color-shade selection feature, which you do by setting `enableShadesSelection` to false. @@ -729,25 +729,25 @@ API reference: [enableTonalPalette](https://pub.dev/documentation/flex_color_pic By default, generation of a selected color's Material-3 tonal-palette is disabled. You can enable it by setting `enableTonalPalette` to true. -When you click/select a color in the color picker and tonal palette is enabled, a 15 shade -Material 3 tonal-palette for the selected color will be generated, always starting with black, -tone 0 for the used seed color and ending in white, tone 100. +When you select a color in the color picker and tonal palette is enabled, a 15-shade +Material-3 tonal-palette for the selected color will be generated. The palette always starts +with black, tone 0 for the used seed color and ends in white, tone 100. The official Material 3 Dart library is used to create the tonal palette from any selected color. The color you select functions a seed color to generate the tonal -palette and might not itself be included and selected in the palette. You can, -of course, click on any color in the generated palette to select and pick a color. +palette and might not itself be included and selected in the palette. You can +click on any color in the generated palette to select and pick a color. Selecting a color in the tonal palette, only selects the color in the palette; it does not update the palette. Only when you select a color from the other color sources in the picker, is that color used as key color, to seed and generate an updated color palette for the selected color. -For more info on Material-3 Color system, see the [official guide](https://m3.material.io/styles/color/the-color-system/key-colors-tones). +For more info on the Material-3 Color system see the [official guide](https://m3.material.io/styles/color/the-color-system/key-colors-tones). The picker item size for tonal palette color indicator items is -10/13 the size of defined width and height. This is done in order to -as far as possible try to match the width of the Primary Material Swatch +10/13 the size of defined width and height. This is done to +as far as possible, try to match the width of the Primary Material Swatch items total width. It has 10 colors, the M3 tonal palette has 15 colors. The goal is to match their width when they are both shown. If you want the tonal palette color indicator items to be the same size as the other color indicators, @@ -834,7 +834,7 @@ will keep their default labels. API reference: [enableOpacity](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorPicker/enableOpacity.html) -You can enable a color opacity slider by setting `enableOpacity` to `true`. With the slider you can adjust the opacity +You can enable a color opacity slider by setting `enableOpacity` to `true`. With the slider, you can adjust the opacity of the selected color. You can adjust opacity from totally opaque at 100%, to totally transparent at 0%. The selected color and the impact of the opacity value on it are visualized by the checkered gradient on the opacity slider, and the selected color's opacity gradient on the slider. The thumb's position is over the resulting color's opacity @@ -845,7 +845,7 @@ so there is a step for every alpha value in the resulting ARGB color value. If t set to a format that includes the alpha, you can see that the alpha value can be adjusted in single increments with the slider. -You cannot pass in the opacity separately to the color picker to get a starting opacity value. If your passed in color +You cannot pass in opacity separately to the color picker to get a starting opacity value. If your passed in color value has opacity in its alpha channel, it will automatically get used, but only if `enableOpacity` is true. If it is false, any opacity or alpha in the color value, or in a color pasted into the picker, is ignored and used as opaque by applying alpha #FF to it. @@ -879,8 +879,9 @@ provide your own localized Material color names. For example: Picker 8 ->The "name that color" feature, using the lookup from 1566 color names, is only available in English and cannot be -translated, in the current version. +> [!NOTE] +> The "name that color" feature using the lookup from 1566 color names is only available in English and cannot be +translated. ### Show Color Code @@ -924,7 +925,7 @@ opacity is enabled, the value the opacity slider is at is kept. However, when se opacity the color had when it was selected and added to the recently used colors list will be used. Selecting a color on the recently used colors list will not move it first in the list. It will keep its current -position. Selecting a color that is already on the list will not add it again. The currently selected color is +position. Selecting a color already on the list will not add it again. The currently selected color is not added to the list until you select a new current color. Picker 10 @@ -935,7 +936,7 @@ You can use this callback to save and restore the recently used colors. To initialize the list when the color picker is created, give it a starting list with `recentColors`. This start list could be a list kept in state during the current app session. It is then used -when the color picker is created and re-opened to show the same recent colors that were used previously during the +when the color picker is created and re-opened to show the same recent colors used previously during the session. The start list could also even have been persisted and restored from a previous session. The live Web demo persists and restores the recently used colors-lists between sessions, in addition to all the settings, you can use it as an example of how to do this. @@ -964,7 +965,7 @@ image below, but it would be below the shade `subheading` and equivalent to it. ## Picker Design -The picker design APIs refer to properties that affect size, shape and spacing of the individual color indicator +The picker design APIs refer to properties that affect the size, shape and spacing of the individual color indicator Widgets inside the color picker, as well as the color wheel and opacity slider sizing. The [ColorIndicator](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/ColorIndicator-class.html) @@ -1017,8 +1018,8 @@ adjusted, below some examples: Picker 16 -If the slider width is not defined (default) it expands to fill available picker width, its minimum allowed width -is 150 dp. The slider height must be from 8 to 50 dp and thumb radius from 12 to 30 dp. +If the slider width is not defined, which it is not by default, it expands to fill available picker width. +Its minimum allowed width is 150 dp. The slider height must be from 8 to 50 dp and thumb radius from 12 to 30 dp. ## Picker Layout @@ -1033,7 +1034,7 @@ The `columnSpacing` refers to the additional vertical spacing between each eleme picker layout. The `padding` and `crossAxisAlignment` are as typically used in Flutter. Please note that `title` widget is not a part of the `Column` body layout of the color picker, and it is not affected by the `crossAxisAlignment` property. You can think of the `title` a bit like an app bar title. It is always start -aligned to leave enough space for 1 to 4 action buttons. The action buttons can optionally be enabled for the title bar, +aligned to leave enough space for one to four action buttons. The action buttons can optionally be enabled for the title bar, and they always appear at the end. Picker 12 @@ -1065,7 +1066,7 @@ The following tooltips exist and use the default values shown in the table below Picker 14 When the keyboard copy/paste shortcuts are enabled, the Copy and Paste tooltips automatically -also receive platform aware keyboard-shortcut info, after the localized tooltip label. On macOS +also receive platform-aware keyboard-shortcut info, after the localized tooltip label. On macOS ' (CMD-C)' is appended to the copy tooltip and ' (CMD-V)' is appended to the paste tooltip. On other platforms ' (CTRL-C)' is appended to the copy tooltip and ' (CTRL-V)' to the paste tooltip. @@ -1086,7 +1087,7 @@ ColorPicker( ); ``` You can define if **OK** and **Close** action buttons are on the top toolbar, or only in the dialog bottom actions -area. The top toolbar buttons are plain icon only buttons. For the bottom dialog action buttons you can choose between +area. The top toolbar buttons are plain icon-only buttons. For the bottom dialog action buttons you can choose between `TextButton`, `OutlinedButton` and `ElevatedButton` for each button. The used icons can be changed from default ones, as can their used tooltips. The labels on the bottom @@ -1105,7 +1106,7 @@ on the toolbar are a nice and compact alternative to selecting color or cancelli Picker 17 -The bottom action buttons, and their style depend on their ambient theme. +The bottom action buttons and their style depend on their ambient theme. There are more dialog action buttons design properties you can adjust, you can, for example, change the order of the OK and Cancel action, or have it be platform adaptive. @@ -1130,7 +1131,7 @@ You can control if the picker has: * Copy and paste action buttons in the top toolbar. * Long press and/or right click copy and paste context-menu. -* Ctrl-C and Ctrl-V keyboard shortcuts, also when not in edit field. +* Ctrl-C and Ctrl-V keyboard shortcuts, also when not in the edit field. Keyboard shortcuts automatically use Command instead of Ctrl on macOS. * A copy color action button in the code entry and display field. @@ -1173,7 +1174,7 @@ layouts on the main surface, where other widgets may have focus, the keyboard sh the color picker's focusable widgets gets focus. When the keyboard copy/paste shortcuts are enabled, the Copy and Paste tooltips by default -also receive platform aware keyboard-shortcut info. After the localized default tooltip label, on macOS +also receive platform-aware keyboard-shortcut info. After the localized default tooltip label, on macOS ' (CMD-C)' is appended to the copy tooltip and ' (CMD-V)' is appended to the paste tooltip. On other platforms ' (CTRL-C)' is appended to the copy tooltip and ' (CTRL-V)' to the paste tooltip. This is shown in the example in the next chapter. @@ -1212,7 +1213,7 @@ enable a context like COPY-PASTE menu that can be triggered either via a long pr typically the right mouse button. The secondary right click is often a good option on Windows and Linux desktop apps, to some extent it may also work -on desktop web browsers. However, desktop browsers' built-in right-click menu also tends to ge triggered by it. +on desktop web browsers. However, desktop browsers' built-in right-click menu also tends to get triggered by it. This menu may get in the way of the color picker's COPY-PASTE menu when secondary click is used in a desktop Web browser. On touch-only devices, or other use cases when a mouse right click is not optimal, the long press option to show the COPY-PASTE menu may work better. @@ -1224,8 +1225,7 @@ Set property `longPressMenu` to `true` (defaults to false) to enable using long picker, to open up the COPY-PASTE context menu. Set property `secondaryOnDesktopLongOnDevice` to `true` (defaults to false), to enable using long press in the color -picker to open up the COPY-PASTE context menu on iOS and Android touch devices. While using secondary mouse-button click -on desktop platforms Windows, Mac and Linux, as well as on desktop-based web browsers. +picker to open up the COPY-PASTE context menu on iOS and Android touch devices. This allows you to still use secondary mouse button click on desktop platforms on Windows, Mac and Linux, as well as on desktop-based web browsers. Set property `secondaryOnDesktopLongOnDeviceAndWeb` to `true` (defaults to false), to enable using long press in the color picker, to open up the COPY-PASTE context menu on Web, iOS and Android touch devices. While using secondary mouse button @@ -1273,7 +1273,7 @@ When pasting color RGB text string values into the color picker, any of the abov parsed to its color value. The color picker's paste parser also filters out none valid HEX code related characters from the string, and -truncates it to the max length of above formats from the right (end) side! +truncates it to the max length of the above formats from the right (end) side! Partial values like for example '0', 'aC', '#334' and '0xFF34' are also allowed and are interpreted as being right aligned in the complete 8-char hex code. @@ -1294,12 +1294,12 @@ The color code entry field can also be set to use the paste parser by setting `e to false). When true, the color code entry field uses the paste parser for keyboard paste shortcuts. A standard text field keyboard paste shortcut, will paste whatever text is in the copy-paste buffer into the field. This is the `false` default behavior here too, with the exception that the field only accepts valid hex value input -chars (0-9, A-F). It thus always filters out and pastes only the acceptable input characters from the paste buffer. +chars (0–9, A–F). It thus always filters out and pastes only the acceptable input characters from the paste buffer. -When `editUsesParsedPaste` property is `true`, the edit field will use the same color paste value parser that is used +When `editUsesParsedPaste` property is `true`, the edit field will use the same color paste value parser used by the other paste actions when the input field is not in focus. This results in a paste action in the entry field that -always fully replaces the content, with the parsed color value of the pasted string data. It does not paste in the -string, in the paste buffer into the text field, it changes it to its parsed value, converted back to a string. +always fully replaces the content with the parsed color value of the pasted string data. It does not paste in the +string in the paste buffer into the text field, it changes it to its parsed value, converted back to a string. Currently, this setting only impacts CTRL-V and CMD-V keyboard shortcut pasting on desktops. The paste on Android and iOS are not intercepted when this setting is true. The false setting is equivalent to past versions (1.x) default behavior when pasting strings into the code entry field. @@ -1316,7 +1316,7 @@ The `snackBarMessage` defines the text message label shown in the paste parse er label is shown in the snack bar when there is a paste parse error, and `snackBarParseError` is true. If the `snackBarMessage` is not defined (is null), it defaults to the combination of the two Material localization -labels `pasteButtonLabel`: `invalidDateFormatLabel`. In English, this will it say +labels `pasteButtonLabel`: `invalidDateFormatLabel`. In English, this will say **Paste: Invalid format**. The `Snackbar`, uses the closest ambient theme with `SnackBarThemeData` for its theming. Below an example of a `copyformat`, `parseShortHexCode`, `editUsesParsedPaste` and `snackBarParseError` configuration, @@ -1371,7 +1371,7 @@ color value, but `onColorChangeEnd` only when the interaction on the wheel and s result from the interaction. If you are using a state logging solution in your application, you can use the **start** and **end** -events to get current selected color state when the change starts. Then store the end result when the +events to get the current selected color state when the change starts. Then store the result when the user has finished changing the color and only if the color value was different. This is useful on the wheel and opacity slider operations, as they will generate a lot of `onColorChanged` events while they are operated, which you may not want to log. If it is applicable to the use-case, then using the `showColorPickerDialog` function described @@ -1416,17 +1416,17 @@ explains how to use the built-in method. The disadvantage of this dialog is that you have to maintain the state yourself. You have to store the color before you open the -dialog, and restore this color if the dialog is cancelled, instead of a color selected. The API can also be a bit +dialog, and restore this color if the dialog is canceled, instead of a color selected. The API can also be a bit cumbersome to use. The above example demonstrates how to do it. ### Function showColorPickerDialog API reference: [showColorPickerDialog](https://pub.dev/documentation/flex_color_picker/latest/flex_color_picker/showColorPickerDialog.html) -The `showColorPickerDialog` function is often simpler to use. Just pass in a build-context for the dialog, and the -required start color value. Call the function, with needed color picker and dialog setup properties, and +The `showColorPickerDialog` function is often simpler to use. Pass in a build-context for the dialog, and the +required start color value. Call the function with needed color picker and dialog setup properties, and await for it to return the selected color when the dialog is closed. -If no color is selected, when the dialog is cancelled or dismissed, then it just returns the passed in start color. +If no color is selected, when the dialog is canceled or dismissed, then it just returns the passed in start color. This picker might be simpler to use in many scenarios. However, it cannot use the feature where colors and themes can be updated in the background behind the dialog, as colors are selected in it, before the dialog is @@ -1435,7 +1435,7 @@ set of recently selected colors. Potentially the callback for the recently used the `showColorPickerDialog`'s exposed APIs, it is however currently not exposed. In many cases, when you just need to open a picker dialog to select a color and move on, this -version offers a simpler API for that. Under the hood it is just a wrapper for the other version with the on change +version offers a simpler API for that. Under the hood, it is just a wrapper for the other version with the on change callbacks. It thus shares all other properties and features with the `ColorPicker`, combined with its `showPickerDialog` method. @@ -1471,8 +1471,9 @@ flutter run -d chrome --web-renderer canvaskit flutter build web --web-renderer canvaskit ``` +> [!NOTE] > **UPDATE Feb 18, 2022:** When using Flutter stable version 2.10.1, the `ImageShader` API -> seems to be available and working also when using --web-renderer html, build. However, if you +> seems available and working also when using --web-renderer html, build. However, if you > run into issues with the opacity slider on web builds, prefer using canvaskit instead of auto or > html renderer when you use the `ColorPicker` in web apps and enable the opacity slider. @@ -1491,7 +1492,7 @@ use keyboard controls to define and select any color. The currently used color picker type selection control is based on the `CupertinoSlidingSegmentedControl` widget. It unfortunately does not support keyboard control. A future version may include additional picker-type -selection controls, that support keyboard navigation and picker "tab" selection. When such controls are added, the +selection controls that support keyboard navigation and picker "tab" selection. When such controls are added, the current version will remain available as default for backward compatibility. # Additional Resources @@ -1505,6 +1506,6 @@ folder, in "example/lib/demo". By studying it, you can see a practical example o it uses. The live Web demo also has tooltips showing the used API behind every demonstrated interactive control. This -can be used as quick reference and to find the actual used API-value as you interactively configure the Web example. +can be used as a quick reference to find the used APIs as you interactively try the Web example. **Happy color picking!** \ No newline at end of file diff --git a/coverage/lcov.info b/coverage/lcov.info index 43083de..147fea4 100644 --- a/coverage/lcov.info +++ b/coverage/lcov.info @@ -1,5 +1,5 @@ SF:lib/src/models/color_picker_action_buttons.dart -DA:57,56 +DA:57,68 DA:293,1 DA:318,1 DA:319,1 @@ -113,97 +113,6 @@ DA:443,3 LF:111 LH:111 end_of_record -SF:lib/src/functions/picker_functions.dart -DA:14,4 -DA:15,4 -DA:16,4 -DA:19,4 -DA:20,2 -DA:21,4 -DA:23,24 -DA:24,4 -DA:29,4 -DA:30,4 -DA:31,4 -DA:32,4 -DA:34,24 -DA:35,4 -DA:44,3 -DA:46,3 -DA:47,2 -DA:48,2 -DA:50,2 -DA:51,2 -DA:52,2 -DA:53,1 -DA:54,1 -DA:59,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:76,4 -DA:86,8 -DA:87,4 -DA:88,12 -DA:90,4 -DA:92,3 -DA:98,4 -DA:99,2 -DA:100,6 -DA:102,4 -DA:106,4 -DA:113,2 -DA:114,1 -DA:122,4 -DA:124,8 -DA:125,4 -DA:129,3 -DA:155,4 -DA:160,8 -DA:161,16 -DA:171,4 -DA:172,4 -DA:173,12 -DA:174,12 -DA:175,12 -DA:176,12 -DA:177,12 -DA:178,12 -DA:179,12 -DA:180,12 -DA:181,12 -DA:182,10 -DA:183,12 -DA:188,3 -DA:189,6 -DA:191,10 -DA:194,15 -LF:67 -LH:67 -end_of_record -SF:lib/src/universal_widgets/dry_intrisinic.dart -DA:20,3 -DA:25,3 -DA:27,3 -DA:32,0 -DA:34,0 -DA:36,0 -DA:37,0 -DA:38,0 -DA:56,1 -DA:61,1 -DA:63,1 -DA:68,0 -DA:70,0 -DA:72,0 -DA:73,0 -DA:74,0 -LF:16 -LH:6 -end_of_record SF:lib/src/color_indicator.dart DA:12,5 DA:26,8 @@ -258,410 +167,403 @@ LH:47 end_of_record SF:lib/src/color_picker.dart DA:69,3 -DA:167,9 -DA:170,3 -DA:171,2 -DA:174,3 -DA:175,2 -DA:177,9 -DA:179,9 -DA:181,6 -DA:182,9 -DA:184,9 -DA:187,7 -DA:189,4 -DA:191,9 -DA:193,9 -DA:195,9 -DA:197,9 -DA:200,6 -DA:201,3 -DA:742,3 -DA:743,3 -DA:767,2 -DA:954,2 -DA:957,2 -DA:961,6 -DA:962,2 -DA:964,4 -DA:965,2 -DA:966,4 -DA:967,1 -DA:968,1 -DA:969,1 +DA:168,9 +DA:171,3 +DA:172,2 +DA:175,3 +DA:176,2 +DA:178,9 +DA:180,9 +DA:182,6 +DA:183,9 +DA:185,9 +DA:188,7 +DA:190,4 +DA:192,9 +DA:194,9 +DA:196,9 +DA:198,9 +DA:201,6 +DA:202,3 +DA:758,3 +DA:759,3 +DA:783,2 DA:970,2 -DA:971,1 -DA:973,3 -DA:976,2 -DA:977,1 -DA:978,1 -DA:979,2 -DA:980,1 +DA:973,2 +DA:977,6 +DA:978,2 +DA:980,4 +DA:981,2 +DA:982,4 +DA:983,1 DA:984,1 -DA:985,2 -DA:986,1 +DA:985,1 +DA:986,2 DA:987,1 -DA:988,1 -DA:989,2 -DA:990,1 -DA:992,3 -DA:995,1 +DA:989,3 +DA:992,2 +DA:993,1 +DA:994,1 +DA:995,2 DA:996,1 -DA:997,1 -DA:998,2 -DA:999,1 +DA:1000,1 +DA:1001,2 +DA:1002,1 DA:1003,1 -DA:1004,2 -DA:1005,1 +DA:1004,1 +DA:1005,2 DA:1006,1 -DA:1007,1 -DA:1008,2 -DA:1009,1 -DA:1011,3 -DA:1014,1 +DA:1008,3 +DA:1011,1 +DA:1012,1 +DA:1013,1 +DA:1014,2 DA:1015,1 -DA:1016,1 -DA:1017,2 -DA:1018,1 +DA:1019,1 +DA:1020,2 +DA:1021,1 DA:1022,1 -DA:1023,2 -DA:1024,1 +DA:1023,1 +DA:1024,2 DA:1025,1 -DA:1026,1 -DA:1027,2 -DA:1028,1 -DA:1030,3 -DA:1033,1 +DA:1027,3 +DA:1030,1 +DA:1031,1 +DA:1032,1 +DA:1033,2 DA:1034,1 -DA:1035,1 -DA:1036,2 -DA:1037,1 +DA:1038,1 +DA:1039,2 +DA:1040,1 DA:1041,1 -DA:1042,2 -DA:1043,1 +DA:1042,1 +DA:1043,2 DA:1044,1 -DA:1045,1 -DA:1046,2 -DA:1047,1 -DA:1049,3 -DA:1052,1 +DA:1046,3 +DA:1049,1 +DA:1050,1 +DA:1051,1 +DA:1052,2 DA:1053,1 -DA:1054,1 -DA:1055,2 -DA:1056,1 -DA:1064,6 -DA:1065,2 -DA:1067,4 -DA:1068,2 -DA:1069,4 +DA:1057,1 +DA:1058,2 +DA:1059,1 +DA:1060,1 +DA:1061,1 +DA:1062,2 +DA:1063,1 +DA:1065,3 +DA:1068,1 +DA:1069,1 DA:1070,1 -DA:1071,1 +DA:1071,2 DA:1072,1 -DA:1073,2 -DA:1074,1 -DA:1076,3 -DA:1079,2 -DA:1080,1 -DA:1081,1 -DA:1082,2 -DA:1083,1 +DA:1080,6 +DA:1081,2 +DA:1083,4 +DA:1084,2 +DA:1085,4 +DA:1086,1 DA:1087,1 -DA:1088,2 -DA:1089,1 +DA:1088,1 +DA:1089,2 DA:1090,1 -DA:1091,1 -DA:1092,2 -DA:1093,1 -DA:1095,3 -DA:1098,1 +DA:1092,3 +DA:1095,2 +DA:1096,1 +DA:1097,1 +DA:1098,2 DA:1099,1 -DA:1100,1 -DA:1101,2 -DA:1102,1 +DA:1103,1 +DA:1104,2 +DA:1105,1 DA:1106,1 -DA:1107,2 -DA:1108,1 +DA:1107,1 +DA:1108,2 DA:1109,1 -DA:1110,1 -DA:1111,2 -DA:1112,1 -DA:1114,3 -DA:1117,1 +DA:1111,3 +DA:1114,1 +DA:1115,1 +DA:1116,1 +DA:1117,2 DA:1118,1 -DA:1119,1 -DA:1120,2 -DA:1121,1 +DA:1122,1 +DA:1123,2 +DA:1124,1 DA:1125,1 -DA:1126,2 -DA:1127,1 +DA:1126,1 +DA:1127,2 DA:1128,1 -DA:1129,1 -DA:1130,2 -DA:1131,1 -DA:1133,3 -DA:1136,1 +DA:1130,3 +DA:1133,1 +DA:1134,1 +DA:1135,1 +DA:1136,2 DA:1137,1 -DA:1138,1 -DA:1139,2 -DA:1140,1 +DA:1141,1 +DA:1142,2 +DA:1143,1 DA:1144,1 -DA:1145,2 -DA:1146,1 +DA:1145,1 +DA:1146,2 DA:1147,1 -DA:1148,1 -DA:1149,2 -DA:1150,1 -DA:1152,3 -DA:1155,1 +DA:1149,3 +DA:1152,1 +DA:1153,1 +DA:1154,1 +DA:1155,2 DA:1156,1 -DA:1157,1 -DA:1158,2 -DA:1159,1 -DA:1169,4 -DA:1170,2 -DA:1171,3 -DA:1173,6 -DA:1178,2 -DA:1184,1 -DA:1189,4 -DA:1190,2 -DA:1191,1 -DA:1193,3 +DA:1160,1 +DA:1161,2 +DA:1162,1 +DA:1163,1 +DA:1164,1 +DA:1165,2 +DA:1166,1 +DA:1168,3 +DA:1171,1 +DA:1172,1 +DA:1173,1 +DA:1174,2 +DA:1175,1 +DA:1185,4 +DA:1186,2 +DA:1187,3 +DA:1189,6 DA:1194,2 -DA:1195,6 -DA:1196,2 -DA:1217,2 -DA:1223,4 -DA:1226,2 -DA:1228,3 -DA:1239,1 -DA:1241,1 -DA:1243,2 -DA:1244,1 -DA:1247,1 -DA:1249,1 -DA:1254,2 -DA:1255,2 +DA:1200,1 +DA:1205,4 +DA:1206,2 +DA:1207,1 +DA:1209,3 +DA:1210,2 +DA:1211,6 +DA:1212,2 +DA:1233,2 +DA:1239,4 +DA:1242,2 +DA:1244,3 +DA:1255,1 +DA:1257,1 +DA:1259,2 DA:1260,1 -DA:1262,2 DA:1263,1 -DA:1266,2 -DA:1365,3 -DA:1367,3 -DA:1369,12 -DA:1370,9 -DA:1372,15 -DA:1374,6 -DA:1375,9 -DA:1378,9 -DA:1380,9 -DA:1382,9 -DA:1384,9 -DA:1387,9 -DA:1389,9 -DA:1393,6 -DA:1398,12 -DA:1400,12 -DA:1401,3 -DA:1403,6 -DA:1407,6 -DA:1409,9 -DA:1411,9 -DA:1413,9 -DA:1414,9 -DA:1417,9 -DA:1418,6 -DA:1421,9 -DA:1422,3 -DA:1424,9 -DA:1427,6 -DA:1428,6 -DA:1429,6 -DA:1431,3 -DA:1432,3 -DA:1434,3 -DA:1435,3 -DA:1436,3 -DA:1439,3 -DA:1440,6 -DA:1442,12 -DA:1444,3 -DA:1446,12 +DA:1265,1 +DA:1270,2 +DA:1271,2 +DA:1276,1 +DA:1278,2 +DA:1279,1 +DA:1282,2 +DA:1381,3 +DA:1383,3 +DA:1385,12 +DA:1386,9 +DA:1388,15 +DA:1390,6 +DA:1391,9 +DA:1394,9 +DA:1396,9 +DA:1398,9 +DA:1400,9 +DA:1403,9 +DA:1405,9 +DA:1409,6 +DA:1414,12 +DA:1416,12 +DA:1417,3 +DA:1419,6 +DA:1423,6 +DA:1425,9 +DA:1427,9 +DA:1429,9 +DA:1430,9 +DA:1433,9 +DA:1434,6 +DA:1437,9 +DA:1438,3 +DA:1440,9 +DA:1443,6 +DA:1444,6 +DA:1445,6 DA:1447,3 -DA:1450,0 -DA:1452,0 -DA:1454,0 -DA:1460,0 -DA:1461,0 -DA:1463,0 -DA:1464,0 -DA:1465,0 -DA:1469,0 -DA:1471,0 -DA:1472,0 -DA:1474,0 -DA:1475,0 +DA:1448,3 +DA:1450,3 +DA:1451,3 +DA:1452,3 +DA:1455,3 +DA:1456,6 +DA:1458,12 +DA:1460,3 +DA:1462,12 +DA:1463,3 +DA:1466,0 +DA:1468,0 +DA:1470,0 +DA:1476,0 DA:1477,0 -DA:1478,0 +DA:1479,0 DA:1480,0 DA:1481,0 -DA:1483,0 -DA:1484,0 -DA:1486,0 +DA:1485,0 DA:1487,0 +DA:1488,0 +DA:1490,0 +DA:1491,0 DA:1493,0 -DA:1495,0 +DA:1494,0 +DA:1496,0 DA:1497,0 +DA:1499,0 DA:1500,0 -DA:1501,0 -DA:1504,0 -DA:1507,0 +DA:1502,0 +DA:1503,0 DA:1509,0 -DA:1512,0 -DA:1515,0 +DA:1511,0 +DA:1513,0 +DA:1516,0 DA:1517,0 +DA:1520,0 DA:1523,0 -DA:1524,0 DA:1525,0 +DA:1528,0 +DA:1531,0 +DA:1533,0 +DA:1539,0 +DA:1540,0 DA:1541,0 -DA:1544,0 -DA:1549,0 -DA:1550,0 -DA:1551,0 -DA:1552,0 -DA:1553,0 -DA:1554,0 -DA:1558,0 -DA:1564,0 +DA:1557,0 +DA:1560,0 +DA:1565,0 DA:1566,0 +DA:1567,0 DA:1568,0 +DA:1569,0 DA:1570,0 -DA:1571,0 DA:1574,0 -DA:1575,0 -DA:1578,0 -DA:1579,0 -DA:1581,0 +DA:1580,0 +DA:1582,0 DA:1584,0 -DA:1585,0 +DA:1586,0 +DA:1587,0 +DA:1590,0 +DA:1591,0 +DA:1594,0 DA:1595,0 -DA:1596,0 +DA:1597,0 DA:1600,0 DA:1601,0 -DA:1602,0 -DA:1604,0 -DA:1608,3 -DA:1610,3 -DA:1617,3 -DA:1618,18 -DA:1621,3 -DA:1622,6 -DA:1623,3 +DA:1611,0 +DA:1612,0 +DA:1616,0 +DA:1617,0 +DA:1618,0 +DA:1620,0 DA:1624,3 -DA:1625,3 -DA:1626,6 -DA:1627,6 -DA:1633,0 -DA:1634,0 -DA:1635,0 -DA:1636,0 -DA:1637,0 -DA:1638,0 -DA:1639,0 -DA:1640,0 -DA:1641,0 -DA:1642,0 -DA:1643,0 -DA:1644,0 -DA:1645,0 -DA:1646,0 +DA:1626,3 +DA:1633,3 +DA:1634,18 +DA:1637,3 +DA:1638,6 +DA:1639,3 +DA:1640,3 +DA:1641,3 +DA:1642,6 +DA:1643,6 +DA:1649,0 DA:1650,0 -DA:1658,6 -DA:1659,4 +DA:1651,0 +DA:1652,0 +DA:1653,0 +DA:1654,0 +DA:1655,0 +DA:1656,0 +DA:1657,0 +DA:1658,0 +DA:1659,0 DA:1660,0 DA:1661,0 -DA:1666,3 -DA:1669,9 -DA:1671,12 -DA:1674,0 -DA:1678,6 -DA:1679,3 -DA:1680,3 -DA:1681,6 -DA:1684,0 -DA:1691,4 -DA:1692,0 -DA:1693,4 -DA:1694,3 -DA:1695,4 -DA:1696,0 -DA:1697,2 -DA:1698,6 -DA:1699,0 +DA:1662,0 +DA:1666,0 +DA:1674,6 +DA:1675,4 +DA:1676,0 +DA:1677,0 +DA:1682,3 +DA:1685,9 +DA:1687,12 +DA:1690,0 +DA:1694,6 +DA:1695,3 +DA:1696,3 +DA:1697,6 DA:1700,0 -DA:1701,2 -DA:1702,6 -DA:1703,2 -DA:1704,3 -DA:1706,4 -DA:1707,6 -DA:1718,7 -DA:1721,3 +DA:1707,4 +DA:1708,0 +DA:1709,4 +DA:1710,3 +DA:1711,4 +DA:1712,0 +DA:1713,2 +DA:1714,6 +DA:1715,0 +DA:1716,0 +DA:1717,2 +DA:1718,6 +DA:1719,2 +DA:1720,3 +DA:1722,4 DA:1723,6 -DA:1724,6 -DA:1725,6 -DA:1726,3 -DA:1729,3 -DA:1733,6 -DA:1734,9 -DA:1737,15 -DA:1741,15 -DA:1745,9 -DA:1746,9 -DA:1747,9 -DA:1748,9 -DA:1752,9 -DA:1753,9 -DA:1756,3 -DA:1757,3 -DA:1758,3 -DA:1760,9 +DA:1734,7 +DA:1737,3 +DA:1739,6 +DA:1740,6 +DA:1741,6 +DA:1742,3 +DA:1745,3 +DA:1749,6 +DA:1750,9 +DA:1753,15 +DA:1757,15 DA:1761,9 +DA:1762,9 DA:1763,9 -DA:1765,9 -DA:1766,0 -DA:1770,0 -DA:1771,0 -DA:1774,0 -DA:1775,0 -DA:1779,3 -DA:1781,3 -DA:1782,6 -DA:1783,3 -DA:1784,6 -DA:1785,3 -DA:1787,6 -DA:1788,9 -DA:1789,9 -DA:1790,9 -DA:1791,9 -DA:1792,2 -DA:1793,2 -DA:1794,8 -DA:1795,2 -DA:1796,4 -DA:1797,6 -DA:1798,2 +DA:1764,9 +DA:1768,9 +DA:1769,9 +DA:1772,3 +DA:1773,3 +DA:1774,3 +DA:1776,9 +DA:1777,9 +DA:1779,9 +DA:1781,9 +DA:1782,0 +DA:1786,0 +DA:1787,0 +DA:1790,0 +DA:1791,0 +DA:1795,3 +DA:1797,3 +DA:1798,6 +DA:1799,3 DA:1800,6 -DA:1801,2 -DA:1803,6 -DA:1804,1 -DA:1809,1 -DA:1811,3 -DA:1812,1 -DA:1813,1 -DA:1815,3 -DA:1816,1 +DA:1801,6 +DA:1802,3 +DA:1804,6 +DA:1805,9 +DA:1806,9 +DA:1807,9 +DA:1808,9 +DA:1809,2 +DA:1810,2 +DA:1811,8 +DA:1812,2 +DA:1813,4 +DA:1814,6 +DA:1815,2 +DA:1817,6 +DA:1818,2 DA:1820,6 DA:1821,1 DA:1826,1 @@ -670,213 +572,212 @@ DA:1829,1 DA:1830,1 DA:1832,3 DA:1833,1 -DA:1837,4 -DA:1838,4 -DA:1839,4 -DA:1843,6 -DA:1844,2 -DA:1845,6 -DA:1846,4 +DA:1837,6 +DA:1838,1 +DA:1843,1 +DA:1845,3 +DA:1846,1 +DA:1847,1 DA:1849,3 -DA:1850,3 -DA:1851,3 -DA:1852,3 -DA:1853,3 -DA:1854,3 -DA:1855,3 -DA:1856,1 -DA:1862,2 -DA:1863,2 -DA:1864,1 -DA:1866,1 -DA:1869,2 -DA:1870,2 -DA:1871,0 -DA:1872,0 -DA:1874,1 -DA:1875,1 -DA:1878,6 -DA:1879,6 -DA:1880,6 -DA:1885,6 -DA:1888,6 -DA:1889,3 -DA:1890,6 -DA:1891,6 -DA:1892,6 -DA:1893,3 -DA:1895,11 -DA:1896,2 -DA:1897,2 -DA:1898,2 -DA:1900,6 -DA:1901,6 +DA:1850,1 +DA:1854,4 +DA:1855,4 +DA:1856,4 +DA:1860,6 +DA:1861,2 +DA:1862,6 +DA:1863,4 +DA:1866,3 +DA:1867,3 +DA:1868,3 +DA:1869,3 +DA:1870,3 +DA:1871,3 +DA:1872,3 +DA:1873,1 +DA:1879,2 +DA:1880,2 +DA:1881,1 +DA:1883,1 +DA:1886,2 +DA:1887,2 +DA:1888,0 +DA:1889,0 +DA:1891,1 +DA:1892,1 +DA:1895,6 +DA:1896,6 +DA:1897,6 DA:1902,6 -DA:1903,6 -DA:1904,6 DA:1905,6 -DA:1906,6 +DA:1906,3 DA:1907,6 -DA:1908,3 -DA:1911,6 -DA:1912,2 -DA:1913,6 +DA:1908,6 +DA:1909,6 +DA:1910,3 +DA:1912,11 +DA:1913,2 DA:1914,2 -DA:1915,4 -DA:1916,4 -DA:1917,2 -DA:1918,2 -DA:1919,4 -DA:1920,4 -DA:1921,4 -DA:1922,4 -DA:1923,4 -DA:1924,2 -DA:1925,2 -DA:1926,1 -DA:1927,2 -DA:1928,3 -DA:1929,3 -DA:1931,1 -DA:1932,2 -DA:1933,1 -DA:1934,1 -DA:1935,1 -DA:1936,1 -DA:1937,1 -DA:1938,1 -DA:1939,1 -DA:1940,1 -DA:1941,1 +DA:1915,2 +DA:1917,6 +DA:1918,6 +DA:1919,6 +DA:1920,6 +DA:1921,6 +DA:1922,6 +DA:1923,6 +DA:1924,6 +DA:1925,3 +DA:1928,6 +DA:1929,2 +DA:1930,6 +DA:1931,2 +DA:1932,4 +DA:1933,4 +DA:1934,2 +DA:1935,2 +DA:1936,4 +DA:1937,4 +DA:1938,4 +DA:1939,4 +DA:1940,4 +DA:1941,2 +DA:1942,2 DA:1943,1 -DA:1944,5 -DA:1946,1 -DA:1947,3 -DA:1948,2 +DA:1944,2 +DA:1945,3 +DA:1946,3 +DA:1948,1 +DA:1949,2 +DA:1950,1 DA:1951,1 -DA:1952,2 +DA:1952,1 DA:1953,1 -DA:1960,6 -DA:1961,4 -DA:1962,4 -DA:1963,2 -DA:1964,6 -DA:1965,4 -DA:1968,6 -DA:1969,4 -DA:1970,4 -DA:1971,2 -DA:1972,6 -DA:1973,4 -DA:1976,6 -DA:1977,3 -DA:1978,6 -DA:1979,6 -DA:1980,12 -DA:1981,3 -DA:1983,11 -DA:1984,1 -DA:1985,1 -DA:1986,1 -DA:1987,2 -DA:1988,0 -DA:1989,0 -DA:1990,0 -DA:1994,6 +DA:1954,1 +DA:1955,1 +DA:1956,1 +DA:1957,1 +DA:1958,1 +DA:1960,1 +DA:1961,5 +DA:1963,1 +DA:1964,3 +DA:1965,2 +DA:1968,1 +DA:1969,2 +DA:1970,1 +DA:1977,6 +DA:1978,4 +DA:1979,4 +DA:1980,2 +DA:1981,6 +DA:1982,4 +DA:1985,6 +DA:1986,4 +DA:1987,4 +DA:1988,2 +DA:1989,6 +DA:1990,4 +DA:1993,6 +DA:1994,3 DA:1995,6 DA:1996,6 -DA:1997,6 -DA:1998,6 -DA:1999,6 -DA:2000,6 -DA:2001,6 -DA:2002,3 -DA:2005,10 -DA:2006,2 -DA:2007,6 -DA:2008,4 -DA:2011,8 -DA:2012,2 -DA:2013,4 -DA:2014,4 -DA:2015,2 -DA:2016,1 -DA:2017,1 -DA:2018,1 -DA:2019,2 -DA:2020,1 -DA:2021,1 -DA:2024,2 +DA:1997,12 +DA:1998,3 +DA:2000,11 +DA:2001,1 +DA:2002,1 +DA:2003,1 +DA:2004,2 +DA:2005,0 +DA:2006,0 +DA:2007,0 +DA:2011,6 +DA:2012,6 +DA:2013,6 +DA:2014,6 +DA:2015,6 +DA:2016,6 +DA:2017,6 +DA:2018,6 +DA:2019,3 +DA:2022,10 +DA:2023,2 +DA:2024,6 DA:2025,4 -DA:2026,2 -DA:2027,8 -DA:2028,2 -DA:2029,4 -DA:2030,2 -DA:2031,8 +DA:2028,8 +DA:2029,2 +DA:2030,4 +DA:2031,4 DA:2032,2 -DA:2033,4 -DA:2034,4 -DA:2035,4 -DA:2036,4 -DA:2037,4 -DA:2038,2 -DA:2040,6 -DA:2043,10 -DA:2044,2 -DA:2045,6 +DA:2033,1 +DA:2034,1 +DA:2035,1 +DA:2036,2 +DA:2037,1 +DA:2038,1 +DA:2041,2 +DA:2042,4 +DA:2043,2 +DA:2044,8 +DA:2045,2 DA:2046,4 -DA:2049,6 -DA:2050,2 -DA:2051,6 -DA:2052,2 -DA:2053,6 +DA:2047,2 +DA:2048,8 +DA:2049,2 +DA:2050,4 +DA:2051,4 +DA:2052,4 +DA:2053,4 +DA:2054,4 DA:2055,2 -DA:2056,2 -DA:2057,2 -DA:2058,4 -DA:2059,2 -DA:2060,4 -DA:2061,4 -DA:2062,2 -DA:2063,0 -DA:2064,0 -DA:2066,0 -DA:2067,0 -DA:2068,0 -DA:2069,0 -DA:2071,0 -DA:2072,0 -DA:2073,0 -DA:2074,0 -DA:2077,0 -DA:2078,0 -DA:2079,0 +DA:2057,6 +DA:2060,10 +DA:2061,2 +DA:2062,6 +DA:2063,4 +DA:2066,6 +DA:2067,2 +DA:2068,6 +DA:2069,2 +DA:2070,6 +DA:2072,2 +DA:2073,2 +DA:2074,2 +DA:2075,4 +DA:2076,2 +DA:2077,4 +DA:2078,4 +DA:2079,2 DA:2080,0 DA:2081,0 -DA:2082,0 DA:2083,0 DA:2084,0 +DA:2085,0 DA:2086,0 -DA:2087,0 +DA:2088,0 DA:2089,0 DA:2090,0 DA:2091,0 -DA:2092,0 -DA:2093,0 +DA:2094,0 DA:2095,0 DA:2096,0 -DA:2109,12 -DA:2110,2 -DA:2111,2 -DA:2113,4 -DA:2114,2 -DA:2115,6 -DA:2116,2 -DA:2117,2 -DA:2118,4 -DA:2120,4 -DA:2127,8 +DA:2097,0 +DA:2098,0 +DA:2099,0 +DA:2100,0 +DA:2101,0 +DA:2103,0 +DA:2104,0 +DA:2106,0 +DA:2107,0 +DA:2108,0 +DA:2109,0 +DA:2110,0 +DA:2112,0 +DA:2113,0 +DA:2126,12 +DA:2127,2 DA:2128,2 DA:2130,4 DA:2131,2 @@ -884,174 +785,183 @@ DA:2132,6 DA:2133,2 DA:2134,2 DA:2135,4 -DA:2145,12 -DA:2146,2 -DA:2147,6 +DA:2137,4 +DA:2144,8 +DA:2145,2 +DA:2147,4 DA:2148,2 -DA:2152,2 -DA:2154,4 -DA:2155,2 -DA:2156,4 -DA:2157,6 -DA:2158,1 -DA:2159,4 -DA:2160,4 -DA:2161,4 -DA:2162,4 -DA:2163,4 -DA:2164,4 +DA:2149,6 +DA:2150,2 +DA:2151,2 +DA:2152,4 +DA:2162,12 +DA:2163,2 +DA:2164,6 DA:2165,2 -DA:2166,0 -DA:2167,0 -DA:2168,0 -DA:2169,0 -DA:2170,0 -DA:2171,0 -DA:2174,0 -DA:2175,0 -DA:2176,0 -DA:2177,0 -DA:2179,0 -DA:2180,0 -DA:2181,0 -DA:2182,0 +DA:2169,2 +DA:2171,4 +DA:2172,2 +DA:2173,4 +DA:2174,6 +DA:2175,1 +DA:2176,4 +DA:2177,4 +DA:2178,4 +DA:2179,4 +DA:2180,4 +DA:2181,4 +DA:2182,2 DA:2183,0 DA:2184,0 +DA:2185,0 DA:2186,0 DA:2187,0 DA:2188,0 -DA:2189,0 -DA:2190,0 DA:2191,0 -DA:2195,4 -DA:2196,4 -DA:2200,8 -DA:2201,2 -DA:2202,4 -DA:2203,2 -DA:2204,6 -DA:2211,6 +DA:2192,0 +DA:2193,0 +DA:2194,0 +DA:2196,0 +DA:2197,0 +DA:2198,0 +DA:2199,0 +DA:2200,0 +DA:2201,0 +DA:2203,0 +DA:2204,0 +DA:2205,0 +DA:2206,0 +DA:2207,0 +DA:2208,0 DA:2212,4 -DA:2213,2 -DA:2214,6 -DA:2215,4 -DA:2218,6 -DA:2219,2 -DA:2220,4 -DA:2221,4 -DA:2222,2 -DA:2223,2 -DA:2224,1 -DA:2225,1 -DA:2226,1 -DA:2228,4 +DA:2213,4 +DA:2217,8 +DA:2218,2 +DA:2219,4 +DA:2220,2 +DA:2221,6 +DA:2228,6 DA:2229,4 -DA:2230,4 -DA:2231,4 +DA:2230,2 +DA:2231,6 DA:2232,4 -DA:2233,4 -DA:2234,4 -DA:2235,4 +DA:2235,6 DA:2236,2 -DA:2238,12 -DA:2246,2 -DA:2254,2 -DA:2260,2 -DA:2263,4 -DA:2264,6 -DA:2265,4 -DA:2269,4 -DA:2270,4 -DA:2273,4 -DA:2275,2 -DA:2276,6 -DA:2277,0 -DA:2278,0 -DA:2281,2 -DA:2282,2 -DA:2285,2 -DA:2286,2 -DA:2288,2 -DA:2293,3 -DA:2294,2 -DA:2296,1 -DA:2304,4 -DA:2305,1 -DA:2306,2 -DA:2307,2 -DA:2310,0 -DA:2312,2 -DA:2316,4 -DA:2317,6 -DA:2318,6 -DA:2322,8 -DA:2323,4 -DA:2327,2 -DA:2329,4 -DA:2331,2 -DA:2334,3 -DA:2336,3 -DA:2337,5 -DA:2339,2 -DA:2340,3 -DA:2343,4 -DA:2348,1 -DA:2349,1 -DA:2353,0 -DA:2354,0 -DA:2357,0 -DA:2359,0 -DA:2368,0 -DA:2369,0 +DA:2237,4 +DA:2238,4 +DA:2239,2 +DA:2240,2 +DA:2241,1 +DA:2242,1 +DA:2243,1 +DA:2245,4 +DA:2246,4 +DA:2247,4 +DA:2248,4 +DA:2249,4 +DA:2250,4 +DA:2251,4 +DA:2252,4 +DA:2253,2 +DA:2255,12 +DA:2263,2 +DA:2271,2 +DA:2277,2 +DA:2280,4 +DA:2281,6 +DA:2282,4 +DA:2286,4 +DA:2287,4 +DA:2290,4 +DA:2292,2 +DA:2293,6 +DA:2294,0 +DA:2295,0 +DA:2298,2 +DA:2299,2 +DA:2302,2 +DA:2303,2 +DA:2305,2 +DA:2310,3 +DA:2311,2 +DA:2313,1 +DA:2321,4 +DA:2322,1 +DA:2323,2 +DA:2324,2 +DA:2327,0 +DA:2329,2 +DA:2333,4 +DA:2334,6 +DA:2335,6 +DA:2339,8 +DA:2340,4 +DA:2344,2 +DA:2346,4 +DA:2348,2 +DA:2351,3 +DA:2353,3 +DA:2354,5 +DA:2356,2 +DA:2357,3 +DA:2360,4 +DA:2365,1 +DA:2366,1 +DA:2370,0 DA:2371,0 -DA:2373,0 DA:2374,0 -DA:2377,0 -DA:2378,0 -DA:2380,0 -DA:2381,0 -DA:2384,0 +DA:2376,0 DA:2385,0 +DA:2386,0 DA:2388,0 -DA:2389,0 +DA:2390,0 +DA:2391,0 +DA:2394,0 +DA:2395,0 +DA:2397,0 +DA:2398,0 +DA:2401,0 DA:2402,0 -DA:2403,0 -DA:2404,0 DA:2405,0 -DA:2408,0 -DA:2409,0 -DA:2415,0 -DA:2418,0 +DA:2406,0 DA:2419,0 DA:2420,0 -DA:2423,0 -DA:2428,0 -DA:2430,0 -DA:2431,0 +DA:2421,0 +DA:2422,0 +DA:2425,0 +DA:2426,0 DA:2432,0 -DA:2433,0 -DA:2442,1 -DA:2444,3 -DA:2445,1 -DA:2446,3 +DA:2435,0 +DA:2436,0 +DA:2437,0 +DA:2440,0 +DA:2445,0 DA:2447,0 DA:2448,0 DA:2449,0 DA:2450,0 -DA:2451,0 -DA:2452,0 -DA:2453,0 -DA:2454,0 -DA:2456,1 -DA:2457,1 -LF:787 -LH:599 +DA:2459,1 +DA:2461,3 +DA:2462,1 +DA:2463,3 +DA:2464,0 +DA:2465,0 +DA:2466,0 +DA:2467,0 +DA:2468,0 +DA:2469,0 +DA:2470,0 +DA:2471,0 +DA:2473,1 +DA:2474,1 +LF:788 +LH:600 end_of_record SF:lib/src/show_color_picker_dialog.dart DA:7,2 DA:682,2 DA:684,2 -DA:742,2 +DA:743,2 LF:4 LH:4 end_of_record @@ -1233,7 +1143,7 @@ DA:767,1 DA:768,3 DA:783,3 DA:784,6 -DA:801,13 +DA:801,16 DA:804,3 DA:805,6 DA:806,3 @@ -1591,7 +1501,7 @@ LF:316 LH:242 end_of_record SF:lib/src/models/color_picker_copy_paste_behavior.dart -DA:58,56 +DA:58,68 DA:348,1 DA:375,1 DA:376,1 @@ -1848,6 +1758,77 @@ DA:352,0 LF:129 LH:89 end_of_record +SF:lib/src/functions/picker_functions.dart +DA:14,4 +DA:15,4 +DA:16,4 +DA:19,4 +DA:20,2 +DA:21,4 +DA:23,24 +DA:24,4 +DA:29,4 +DA:30,4 +DA:31,4 +DA:32,4 +DA:34,24 +DA:35,4 +DA:44,3 +DA:46,3 +DA:47,2 +DA:48,2 +DA:50,2 +DA:51,2 +DA:52,2 +DA:53,1 +DA:54,1 +DA:59,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:65,1 +DA:66,1 +DA:67,1 +DA:76,4 +DA:86,8 +DA:87,4 +DA:88,12 +DA:90,4 +DA:92,3 +DA:98,4 +DA:99,2 +DA:100,6 +DA:102,4 +DA:106,4 +DA:113,2 +DA:114,1 +DA:122,4 +DA:124,8 +DA:125,4 +DA:129,3 +DA:155,4 +DA:160,8 +DA:161,16 +DA:171,4 +DA:172,4 +DA:173,12 +DA:174,12 +DA:175,12 +DA:176,12 +DA:177,12 +DA:178,12 +DA:179,12 +DA:180,12 +DA:181,12 +DA:182,10 +DA:183,12 +DA:188,3 +DA:189,6 +DA:191,10 +DA:194,15 +LF:67 +LH:67 +end_of_record SF:lib/src/widgets/color_picker_toolbar.dart DA:14,2 DA:24,2 @@ -1967,11 +1948,11 @@ DA:121,0 DA:122,0 DA:125,2 DA:129,4 -DA:140,13 +DA:140,16 DA:146,4 DA:154,0 DA:156,0 -DA:164,13 +DA:164,16 DA:170,4 DA:178,0 DA:180,0 @@ -2030,9 +2011,9 @@ DA:131,3 DA:132,2 DA:133,3 DA:135,3 -DA:136,9 -DA:137,3 -DA:138,3 +DA:136,8 +DA:137,2 +DA:138,2 DA:140,3 DA:145,1 DA:151,2 @@ -2229,6 +2210,26 @@ DA:148,0 LF:35 LH:9 end_of_record +SF:lib/src/universal_widgets/dry_intrisinic.dart +DA:20,3 +DA:25,3 +DA:27,3 +DA:32,0 +DA:34,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:56,1 +DA:61,1 +DA:63,1 +DA:68,0 +DA:70,0 +DA:72,0 +DA:73,0 +DA:74,0 +LF:16 +LH:6 +end_of_record SF:lib/src/universal_widgets/if_wrapper.dart DA:32,5 DA:38,5 diff --git a/example/lib/demo/utils/app.dart b/example/lib/demo/utils/app.dart index f5bb785..3c8dbf9 100644 --- a/example/lib/demo/utils/app.dart +++ b/example/lib/demo/utils/app.dart @@ -9,7 +9,7 @@ class App { // Web demo with inside the app. Shown on the start screen in the demo, // so people testing it don't have to ask. Also info for the About screen. static const String appName = 'FlexColorPicker'; - static const String version = '3.5.0-dev.1'; + static const String version = '3.5.0'; static const String packageVersion = 'FlexColorPicker package $version'; static final Uri packageUri = Uri( scheme: 'https', diff --git a/example/lib/main.dart b/example/lib/main.dart index a500131..d41cfff 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -226,7 +226,7 @@ class _ColorPickerPageState extends State { child: Card( elevation: 2, child: ColorPicker( - // Use the screenPickerColor as start color. + // Use the screenPickerColor as color. color: screenPickerColor, // Update the screenPickerColor using the callback. onColorChanged: (Color color) => diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 4e0d7da..66fefbe 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -21,8 +21,8 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c - url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399 PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 diff --git a/example/pubspec.lock b/example/pubspec.lock index d922ca9..99e4114 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -119,15 +119,15 @@ packages: path: ".." relative: true source: path - version: "3.5.0-dev.1" + version: "3.5.0" flex_seed_scheme: dependency: transitive description: name: flex_seed_scheme - sha256: "116dc56093aa4e64d2f03135957b5ef61b1134a4a4990c66f76bc635903d0d8c" + sha256: fb66cdb8ca89084e79efcad2bc2d9deb144666875116f08cdd8d9f8238c8b3ab url: "https://pub.dev" source: hosted - version: "2.0.0-dev.1" + version: "2.0.0" flutter: dependency: "direct main" description: flutter @@ -670,4 +670,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.3.0 <4.0.0" - flutter: ">=3.22.0-0.3.pre" + flutter: ">=3.22.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index b90301d..66e7f61 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,10 +1,10 @@ name: color_picker_example description: Two examples of how to use the FlexColorPicker package. -version: 3.5.0-dev.1 +version: 3.5.0 publish_to: 'none' environment: sdk: '>=2.19.0 <4.0.0' - flutter: '>=3.22.0-0.3.pre' + flutter: '>=3.22.0' dependencies: # https://pub.dev/packages/flex_color_picker diff --git a/lib/src/color_picker.dart b/lib/src/color_picker.dart index 6978a66..66a0203 100644 --- a/lib/src/color_picker.dart +++ b/lib/src/color_picker.dart @@ -87,6 +87,7 @@ class ColorPicker extends StatefulWidget { this.includeIndex850 = false, this.enableTonalPalette = false, // Layout + this.mainAxisSize = MainAxisSize.max, this.crossAxisAlignment = CrossAxisAlignment.center, this.padding = const EdgeInsets.all(16), this.columnSpacing = 8, @@ -202,17 +203,42 @@ class ColorPicker extends StatefulWidget { 'The maxRecentColors must be >= $_minRecentColors ' 'and <= $_maxRecentColors.'); - /// The active color selection when the color picker is created. + /// The active color selection in the color picker. + /// + /// Also used as initial value when the color picker is created. + /// + /// Use the callback [onColorChanged] to get the new color values from + /// the picker and update the [color] in the parent widget. final Color color; /// Required [ValueChanged] callback, called when user selects /// a new color with new color value. /// + /// /// Called every time the color value changes when operating thumbs on the /// color wheel or color or transparency sliders /// /// Changing which picker type is viewed does not trigger this callback, it /// is not triggered until a color in the viewed picker is selected. + /// + /// The picker passes the new value to the callback but does not actually + /// change state until the parent widget rebuilds the color picker with + /// the new value. + /// + /// The callback provided to [onColorChanged] should update the state of the + /// parent [StatefulWidget] using the [State.setState] method, so that the + /// parent gets rebuilt; for example: + /// + /// ```dart + /// ColorPicker( + /// color: _pickerColor, + /// onChanged: (Color color) { + /// setState(() { + /// _pickerColor = color; + /// }); + /// }, + /// ) + /// ``` final ValueChanged onColorChanged; /// Optional [ValueChanged] callback. Called when user starts color selection @@ -287,6 +313,21 @@ class ColorPicker extends StatefulWidget { /// Defaults to CrossAxisAlignment.center. final CrossAxisAlignment crossAxisAlignment; + /// How much space should be occupied in the color picker's vertical axis. + /// + /// After allocating space to children, in the ColorPicker column there + /// might be some remaining free space. This value controls whether to + /// maximize or minimize the amount of + /// free space, subject to the incoming layout constraints. + /// + /// If some children have a non-zero flex factors (and none have a fit of + /// [FlexFit.loose]), they will expand to consume all the available space and + /// there will be no remaining free space to maximize or minimize, making this + /// value irrelevant to the final layout. + /// + /// Defaults to [MainAxisSize.max] like [Column] does as well. + final MainAxisSize mainAxisSize; + /// Padding around the entire color picker content. /// /// Defaults to const EdgeInsets.all(16). @@ -1781,7 +1822,7 @@ class _ColorPickerState extends State { child: Padding( padding: widget.padding, child: Column( - mainAxisSize: MainAxisSize.min, + mainAxisSize: widget.mainAxisSize, crossAxisAlignment: widget.crossAxisAlignment, children: [ // Show title bar widget if we have one. @@ -1931,6 +1972,7 @@ class _ColorPickerState extends State { }, onChanged: (Color color) { setState(() { + _fromInternal = true; _tappedColor = color; _selectedColor = color; _wheelShouldUpdate = false; diff --git a/lib/src/show_color_picker_dialog.dart b/lib/src/show_color_picker_dialog.dart index f4b83e2..343f29c 100644 --- a/lib/src/show_color_picker_dialog.dart +++ b/lib/src/show_color_picker_dialog.dart @@ -8,7 +8,7 @@ Future showColorPickerDialog( /// Required build context for the dialog BuildContext context, - /// The active color selection when the color picker is created. + /// The active color selection when the color picker dialog is created. Color color, { /// A [ColorPickerType] to bool map. Defines which pickers are enabled in the /// color picker's sliding selector and thus available as color pickers. @@ -66,6 +66,21 @@ Future showColorPickerDialog( /// Defaults to false. final bool enableTonalPalette = false, + /// How much space should be occupied in the color picker's vertical axis. + /// + /// After allocating space to children, in the ColorPicker column there + /// might be some remaining free space. This value controls whether to + /// maximize or minimize the amount of + /// free space, subject to the incoming layout constraints. + /// + /// If some children have a non-zero flex factors (and none have a fit of + /// [FlexFit.loose]), they will expand to consume all the available space and + /// there will be no remaining free space to maximize or minimize, making this + /// value irrelevant to the final layout. + /// + /// Defaults to `MainAxisSize.max` like Column does as well. + final MainAxisSize mainAxisSize = MainAxisSize.max, + /// Cross axis alignment used to layout the main content of the /// color picker in its column layout. /// @@ -689,6 +704,7 @@ Future showColorPickerDialog( includeIndex850: includeIndex850, enableTonalPalette: enableTonalPalette, crossAxisAlignment: crossAxisAlignment, + mainAxisSize: mainAxisSize, padding: padding, columnSpacing: columnSpacing, toolbarSpacing: toolbarSpacing, diff --git a/pubspec.lock b/pubspec.lock index 3069621..971fcba 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -109,10 +109,10 @@ packages: dependency: "direct main" description: name: flex_seed_scheme - sha256: "116dc56093aa4e64d2f03135957b5ef61b1134a4a4990c66f76bc635903d0d8c" + sha256: fb66cdb8ca89084e79efcad2bc2d9deb144666875116f08cdd8d9f8238c8b3ab url: "https://pub.dev" source: hosted - version: "2.0.0-dev.1" + version: "2.0.0" flutter: dependency: "direct main" description: flutter @@ -263,10 +263,10 @@ packages: dependency: "direct dev" description: name: patrol_finders - sha256: ac33527cc1b63e3aa131dbd7107cfda8ee2df0fb4a4a423c067174a2e60db77b + sha256: fbc98e89e1df4568f638389f4b320b6adb5d8e98d9d2ed86e370e01f4708787c url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3-dev.1" pool: dependency: transitive description: @@ -466,4 +466,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.3.0 <4.0.0" - flutter: ">=3.22.0-0.3.pre" + flutter: ">=3.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index c82ef9e..a2862dd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flex_color_picker description: A customizable Flutter primary, accent and custom color picker. Includes an optional HSV wheel color picker. -version: 3.5.0-dev.1 +version: 3.5.0 homepage: https://github.com/rydmike/flex_color_picker repository: https://github.com/rydmike/flex_color_picker issue_tracker: https://github.com/rydmike/flex_color_picker/issues @@ -25,12 +25,12 @@ topics: environment: sdk: '>=3.0.0 <4.0.0' - flutter: '>=3.22.0-0.3.pre' + flutter: '>=3.22.0' dependencies: # FlexSeedScheme package, by Mike Rydstrom, rydmike.com (@rydmike). # https://pub.dev/packages/flex_seed_scheme - flex_seed_scheme: ^2.0.0-dev.1 + flex_seed_scheme: ^2.0.0 flutter: sdk: flutter @@ -39,7 +39,7 @@ dev_dependencies: collection: flutter_test: sdk: flutter - patrol_finders: 2.0.2 + patrol_finders: 2.0.3-dev.1 test: flutter: diff --git a/test/color_picker_patrol_test.dart b/test/color_picker_patrol_test.dart index 8115b62..1172b8e 100644 --- a/test/color_picker_patrol_test.dart +++ b/test/color_picker_patrol_test.dart @@ -3,1617 +3,1617 @@ // ignore_for_file: flutter_style_todos -void main() {} - -// import 'package:flex_color_picker/flex_color_picker.dart'; -// import 'package:flex_color_picker/src/widgets/color_picker_toolbar.dart'; -// import 'package:flex_color_picker/src/widgets/opacity/opacity_slider.dart'; -// import 'package:flex_color_picker/src/widgets/recent_colors.dart'; -// import 'package:flutter/foundation.dart'; -// import 'package:flutter/material.dart'; -// import 'package:flutter_test/flutter_test.dart'; -// import 'package:patrol_finders/patrol_finders.dart'; -// -// // ignore_for_file: unnecessary_null_comparison -// -// //**************************************************************************** -// // FlexColorPicker ColorPicker Widget tests -// //**************************************************************************** -// void main() { -// const ValueKey testKey = ValueKey('test'); -// -// group('PAT1: Patrol Finder ColorPicker Tests', () { -// debugDefaultTargetPlatformOverride = null; -// -// patrolWidgetTest( -// 'PAT1.1: Patrol test finds correct primary and accent pickers and colors', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: ColorPicker( -// key: testKey, -// onColorChanged: (Color color) { -// resultColor = color; -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// expect(resultColor.value, Colors.purple.value); -// await $(ColorIndicator).at(20).tap(); -// expect(resultColor.value, Colors.purple[100]!.value); -// -// // Test accent color picker. -// expect(find.text('Accent'), findsOneWidget); -// await $('Accent').tap(); -// await $(ColorIndicator).tap(); -// expect(resultColor.value, Colors.redAccent.value); -// await $(ColorIndicator).at(5).tap(); -// expect(resultColor.value, Colors.blueAccent.value); -// await $(ColorIndicator).at(18).tap(); -// expect(resultColor.value, Colors.blueAccent[400]!.value); -// }, -// ); -// -// // -// // ************************************************************************* -// // -// -// patrolWidgetTest( -// 'PAT1.2: Patrol test configured pickers and colors', -// // config: PatrolTestConfig(findTimeout: const Duration(seconds: 10)), -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// Color startColor = Colors.blue; -// Color endColor = Colors.blue; -// List recentColors = []; -// -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: ColorPicker( -// key: testKey, -// color: Colors.red, // Primary picker s default selected -// onColorChanged: (Color color) { -// resultColor = color; -// }, -// onColorChangeStart: (Color color) { -// startColor = color; -// }, -// onColorChangeEnd: (Color color) { -// endColor = color; -// }, -// pickersEnabled: const { -// ColorPickerType.both: true, -// ColorPickerType.primary: false, -// ColorPickerType.accent: false, -// ColorPickerType.bw: true, -// ColorPickerType.custom: true, -// ColorPickerType.customSecondary: true, -// ColorPickerType.wheel: true, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: false, -// dialogActionOnlyOkButton: true, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// ), -// hasBorder: true, -// borderRadius: 10, -// borderColor: Colors.black, -// wheelWidth: 32, -// wheelSquarePadding: 4, -// wheelSquareBorderRadius: 6, -// wheelHasBorder: true, -// title: const Text('Title'), -// heading: const Text('Heading'), -// subheading: const Text('Subheading'), -// tonalSubheading: const Text('Tonal'), -// wheelSubheading: const Text('Wheel heading'), -// opacitySubheading: const Text('Opacity heading'), -// recentColorsSubheading: const Text('Recent colors heading'), -// showMaterialName: true, -// showColorName: true, -// showColorCode: true, -// colorCodeHasColor: true, -// showColorValue: true, -// showRecentColors: true, -// maxRecentColors: 4, -// recentColors: recentColors, -// onRecentColorsChanged: (List colors) { -// recentColors = colors; -// }, -// selectedPickerTypeColor: Colors.white, -// customColorSwatchesAndNames: , String>{ -// ColorTools.createPrimarySwatch(const Color(0xFF6200EE)): -// 'Guide Purple', -// ColorTools.createPrimarySwatch(const Color(0xFF3700B3)): -// 'Guide Purple Variant', -// ColorTools.createAccentSwatch(const Color(0xFF03DAC6)): -// 'Guide Teal', -// }, -// customSecondaryColorSwatchesAndNames: , -// String>{ -// ColorTools.createPrimarySwatch(const Color(0xFF00EE4B)): -// 'Option 1', -// ColorTools.createPrimarySwatch(const Color(0xFF92B300)): -// 'Option 2', -// }, -// ), -// ), -// ); -// -// // We should NOT find the separated primary and accent pickers -// expect(find.text('Primary'), findsNothing); -// expect(find.text('Accent'), findsNothing); -// // Test titles -// expect(find.text('Title'), findsOneWidget); -// expect(find.text('Heading'), findsOneWidget); -// expect(find.text('Subheading'), findsOneWidget); -// expect(find.text('Tonal'), findsOneWidget); -// expect(find.text('Opacity heading'), findsOneWidget); -// expect(find.text('Recent colors heading'), findsOneWidget); -// -// // Test primary & accent color picker. -// expect(find.text('Primary & Accent'), findsOneWidget); -// await $('Primary & Accent').tap(); -// await $(ColorIndicator).at(1).tap(); -// expect(startColor.value, Colors.red.value); -// expect(endColor.value, Colors.redAccent.value); -// expect(resultColor.value, Colors.redAccent.value); -// // Test recent colors -// expect(recentColors.contains(Color(Colors.red.value)), true); -// await $(ColorIndicator).at(34).tap(); -// expect(startColor.value, Colors.redAccent.value); -// expect(endColor.value, Colors.grey.value); -// expect(resultColor.value, Colors.grey.value); -// // Test recent colors -// expect(recentColors.contains(Color(Colors.red.value)), true); -// expect(recentColors.contains(Color(Colors.redAccent.value)), true); -// await $(ColorIndicator).at(44).tap(); -// expect(startColor.value, Colors.grey.value); -// expect(endColor.value, Colors.grey[850]!.value); -// expect(resultColor.value, Colors.grey[850]!.value); -// // Test recent colors -// expect(recentColors.contains(Color(Colors.red.value)), true); -// expect(recentColors.contains(Color(Colors.redAccent.value)), true); -// expect(recentColors.contains(Color(Colors.grey.value)), true); -// -// // Test black & white color picker. -// expect(find.text('Black & White'), findsOneWidget); -// await $('Black & White').tap(); -// // Black shade color test -// await $(ColorIndicator).at(8).tap(); -// expect(startColor.value, Colors.grey[850]!.value); -// expect(endColor.value, ColorTools.blackShade[600]!.value); -// expect(resultColor.value, ColorTools.blackShade[600]!.value); -// // Test recent colors -// expect(recentColors.contains(Color(Colors.red.value)), true); -// expect(recentColors.contains(Color(Colors.redAccent.value)), true); -// expect(recentColors.contains(Color(Colors.grey.value)), true); -// expect(recentColors.contains(Color(Colors.grey[850]!.value)), true); -// // White shade color test -// await $(ColorIndicator).at(1).tap(); -// expect(resultColor.value, ColorTools.whiteShade[500]!.value); -// // Test recent colors -// expect(recentColors.contains(Color(Colors.red.value)), -// false); // 4 max, no red -// expect(recentColors.contains(Color(Colors.redAccent.value)), true); -// expect(recentColors.contains(Color(Colors.grey.value)), true); -// expect(recentColors.contains(Color(Colors.grey[850]!.value)), true); -// expect(recentColors.contains(Color(ColorTools.blackShade[600]!.value)), -// true); -// await $(ColorIndicator).at(2).tap(); -// expect(resultColor, Colors.white); -// await $(ColorIndicator).at(11).tap(); -// expect(resultColor.value, ColorTools.whiteShade[900]!.value); -// -// // Test Custom color picker. -// expect(find.text('Custom'), findsOneWidget); -// await $('Custom').tap(); -// await $(ColorIndicator).at(1).tap(); -// expect(startColor.value, ColorTools.whiteShade[900]!.value); -// expect(endColor, const Color(0xFF3700B3)); -// expect(resultColor, const Color(0xFF3700B3)); -// -// // Test Option color picker. -// expect(find.text('Option'), findsOneWidget); -// await $('Option').tap(); -// await $(ColorIndicator).at(1).tap(); -// expect(startColor, const Color(0xFF3700B3)); -// expect(endColor, const Color(0xFF92B300)); -// expect(resultColor, const Color(0xFF92B300)); -// -// // Test Wheel color picker. -// expect(find.text('Wheel'), findsOneWidget); -// await $('Wheel').tap(); -// expect(find.text('Wheel heading'), findsOneWidget); -// expect(find.text('Tonal'), findsOneWidget); -// // The 10th ColorIndicator will be first tonal and always black. -// await $(ColorIndicator).at(10).tap(); -// expect(startColor, const Color(0xFF92B300)); -// expect(endColor, Colors.black); -// expect(resultColor, Colors.black); -// await $(ColorIndicator).at(16).tap(); -// expect(startColor, Colors.black); -// expect(endColor, const Color(0xFF688000)); -// expect(resultColor, const Color(0xFF688000)); -// // Find the ColorWheelPicker -// expect(find.byType(ColorWheelPicker), findsOneWidget); -// // Tap center of the ColorWheelPicker -// await $(ColorWheelPicker).tap(); -// expect(resultColor, const Color(0xff748040)); -// -// // The 24th ColorIndicator will be last tonal and always white. -// await $(ColorIndicator).at(24).tap(); -// expect(resultColor, Colors.white); -// -// // Find the RecentColors -// expect(find.byType(RecentColors), findsOneWidget); -// // Recent colors has 4 color indicators, since we set max to 4. -// expect($(RecentColors).$(ColorIndicator), findsNWidgets(4)); -// // Let's tap the last one, we need to scroll to it first. -// await $(RecentColors).$(ColorIndicator).at(3).scrollTo().tap(); -// // Result should be 5 result color from earlier above. -// expect(resultColor, const Color(0xff92b300)); -// -// // Find the OpacitySlider -// // TODO(rydmike): Get the slider test working! -// expect(find.byType(OpacitySlider), findsOneWidget); -// // expect(find.byType(Slider), findsOneWidget); -// // Tap center of the OpacitySlider -// // await $(OpacitySlider) -// // .scrollTo(settlePolicy: SettlePolicy.trySettle) -// // .tap(); -// -// // Find the Text entry -// expect(find.byType(ColorCodeField), findsOneWidget); -// expect(find.byType(TextField), findsOneWidget); -// // TODO(rydmike): Get the color code entry test working! -// // await $(find.byType(TextField)).enterText('613E42'); -// // await $(find.byType(ColorCodeField)).enterText('613E42'); -// // expect(resultColor, const Color(0xFF613E42)); -// -// // Find the ToolBar -// expect(find.byType(ColorPickerToolbar), findsOneWidget); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Copy the Color -// await $(ColorPickerToolbar).$(IconButton).at(0).tap( -// settlePolicy: SettlePolicy.trySettle, -// visibleTimeout: const Duration(seconds: 1), -// settleTimeout: const Duration(seconds: 2), -// ); -// // TODO(rydmike): Figure out how to test clipboard copy/paste. -// // We should have some clipboard data from above tap. But the below -// // attempt to get the data never completes. The code flow hit paths -// // from above also indicates the buffer is empty after the tap above. -// // final ClipboardData? clipData = -// // await Clipboard.getData(Clipboard.kTextPlain); -// // debugPrint('Clip data: $clipData'); -// -// // TEST COPY/PASTE via toolbar buttons -// // Go to another tab select a new color -// await $('Primary & Accent').tap(); -// await $(ColorIndicator).at(1).tap(); -// expect(resultColor.value, Colors.redAccent.value); -// // Copy in the redAccent color -// await $(ColorPickerToolbar).$(IconButton).at(0).tap( -// settlePolicy: SettlePolicy.trySettle, -// visibleTimeout: const Duration(seconds: 1), -// settleTimeout: const Duration(seconds: 2), -// ); -// // Select pink color -// await $(ColorIndicator).at(2).tap(); -// expect(resultColor.value, Colors.pink.value); -// // Paste in the red accent value color -// await $(ColorPickerToolbar).$(IconButton).at(1).tap( -// settlePolicy: SettlePolicy.trySettle, -// visibleTimeout: const Duration(seconds: 1), -// settleTimeout: const Duration(seconds: 2), -// ); -// // This is the color we should find but do not since copy did nothing. -// // The paste wont work either. -// // expect(Color(resultColor.value), Color(Colors.redAccent.value)); -// // Color(0xffe91e63); -// }, -// ); -// -// // Test issue https://github.com/rydmike/flex_color_picker/issues/71 -// patrolWidgetTest( -// 'PAT1.3: Patrol widget test for issue #71 ', -// (PatrolTester $) async { -// Color resultColor = const Color(0xFF613E42); -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: ColorPicker( -// key: testKey, -// color: resultColor, -// enableTonalPalette: true, -// onColorChanged: (Color color) { -// resultColor = color; -// }, -// width: 40, -// height: 40, -// borderRadius: 4, -// spacing: 5, -// runSpacing: 5, -// wheelDiameter: 155, -// showMaterialName: true, -// showColorName: true, -// showColorCode: true, -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: true, -// ColorPickerType.wheel: true, -// }, -// actionButtons: const ColorPickerActionButtons( -// okButton: false, -// closeButton: true, -// okTooltip: 'DO', -// closeTooltipIsClose: false, -// toolIconsThemeData: IconThemeData( -// color: Colors.blue, -// size: 20, -// opacity: 0.95, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// dialogActionOnlyOkButton: true, -// ), -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Primary'), findsOneWidget); -// expect(find.text('Accent'), findsOneWidget); -// expect(find.text('Custom'), findsNothing); // We gave no custom colors -// expect(find.text('Wheel'), findsOneWidget); -// -// // Find the ColorWheelPicker, we are on it by default -// expect(find.byType(ColorWheelPicker), findsOneWidget); -// // Tap sliding selector on wheel -// await $('Wheel').tap(); -// -// // The 14th ColorIndicator will be 5th tonal -// await $(ColorIndicator).at(14).tap(); -// expect(resultColor, const Color(0xFF7D2939)); -// -// // Tap primary slider, no crash! This crashed without the FIX for #71 -// await $('Primary').tap(); -// // Tap a Material red shade color -// await $(ColorIndicator).at(22).tap(); -// expect(resultColor.value, Colors.red[300]!.value); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.4: Patrol test dialog - default labels, text buttons-no-icons', -// (PatrolTester $) async { -// Color resultColor = Colors.orange; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: false, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// // dialogActionOnlyOkButton: false, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// ), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// // expect(resultColor.value, Colors.purple.value); -// await $(ColorIndicator).at(20).tap(); -// // expect(resultColor.value, Colors.purple[100]!.value); -// -// // Test accent color picker. -// expect(find.text('Accent'), findsOneWidget); -// await $('Accent').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.redAccent.value); -// await $(ColorIndicator).at(5).tap(); -// // expect(resultColor.value, Colors.blueAccent.value); -// await $(ColorIndicator).at(18).tap(); -// -// expect(find.byType(TextButton), findsExactly(2)); -// await $(TextButton).at(1).tap(); -// expect(Color(resultColor.value), Color(Colors.blueAccent[400]!.value)); -// const Color(0xff2979ff); -// const Color(0xffff9800); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// // expect(resultColor.value, Colors.purple.value); -// expect(find.text('OK'), findsOneWidget); -// await $('OK').tap(); -// expect(resultColor.value, Colors.purple.value); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// expect(find.text('Cancel'), findsOneWidget); -// await $('Cancel').tap(); -// expect(resultColor.value, Colors.purple.value); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.4-icons: Patrol test dialog - default labels, text buttons-icons', -// (PatrolTester $) async { -// Color resultColor = Colors.orange; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: false, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionIcons: true, -// dialogActionButtons: true, -// // dialogActionOnlyOkButton: false, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// ), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// // expect(resultColor.value, Colors.purple.value); -// await $(ColorIndicator).at(20).tap(); -// // expect(resultColor.value, Colors.purple[100]!.value); -// -// // Test accent color picker. -// expect(find.text('Accent'), findsOneWidget); -// await $('Accent').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.redAccent.value); -// await $(ColorIndicator).at(5).tap(); -// // expect(resultColor.value, Colors.blueAccent.value); -// await $(ColorIndicator).at(18).tap(); -// -// expect(find.text('OK'), findsOneWidget); -// await $('OK').tap(); -// expect(Color(resultColor.value), Color(Colors.blueAccent[400]!.value)); -// const Color(0xff2979ff); -// const Color(0xffff9800); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// // expect(resultColor.value, Colors.purple.value); -// expect(find.text('OK'), findsOneWidget); -// await $('OK').tap(); -// expect(resultColor.value, Colors.purple.value); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// expect(find.text('Cancel'), findsOneWidget); -// await $('Cancel').tap(); -// expect(resultColor.value, Colors.purple.value); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.5: Patrol test dialog - custom labels, filled buttons-no-icons', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: false, -// }, -// columnSpacing: 4, -// toolbarSpacing: 0, -// shadesSpacing: 0, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// // dialogActionOnlyOkButton: false, -// dialogCancelButtonLabel: 'CLOSE', -// dialogOkButtonLabel: 'USE', -// dialogOkButtonType: ColorPickerActionButtonType.filled, -// dialogCancelButtonType: -// ColorPickerActionButtonType.filled, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// feedbackParseError: true, -// parseShortHexCode: true, -// ), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// // expect(resultColor.value, Colors.purple.value); -// expect(find.text('USE'), findsOneWidget); -// await $('USE').tap(); -// expect(Color(resultColor.value), Color(Colors.purple.value)); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// expect(find.text('CLOSE'), findsOneWidget); -// await $('CLOSE').tap(); -// expect(resultColor.value, Colors.purple.value); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.5-icon: Patrol test dialog - custom labels, filled buttons-icons', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: false, -// }, -// columnSpacing: 4, -// toolbarSpacing: 0, -// shadesSpacing: 0, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// // dialogActionOnlyOkButton: false, -// dialogCancelButtonLabel: 'CLOSE', -// dialogOkButtonLabel: 'USE', -// dialogActionIcons: true, -// dialogOkButtonType: ColorPickerActionButtonType.filled, -// dialogCancelButtonType: -// ColorPickerActionButtonType.filled, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// feedbackParseError: true, -// parseShortHexCode: true, -// ), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// // expect(resultColor.value, Colors.purple.value); -// expect(find.text('USE'), findsOneWidget); -// await $('USE').tap(); -// expect(Color(resultColor.value), Color(Colors.purple.value)); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// expect(find.text('CLOSE'), findsOneWidget); -// await $('CLOSE').tap(); -// expect(resultColor.value, Colors.purple.value); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.6: Patrol test dialog - custom labels, filledTonal-no-icons', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// platform: TargetPlatform.windows, -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: false, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// closeIsLast: false, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// dialogCancelButtonLabel: 'CLOSER', -// dialogOkButtonLabel: 'USE', -// dialogOkButtonType: -// ColorPickerActionButtonType.filledTonal, -// dialogCancelButtonType: -// ColorPickerActionButtonType.filledTonal, -// dialogActionOrder: -// ColorPickerActionButtonOrder.adaptive, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// feedbackParseError: true, -// parseShortHexCode: true, -// ), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// // expect(resultColor.value, Colors.purple.value); -// expect(find.text('USE'), findsOneWidget); -// await $('USE').tap(); -// expect(Color(resultColor.value), Color(Colors.purple.value)); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// // Close via Cancel button -// expect(find.text('CLOSER'), findsOneWidget); -// await $('CLOSER').tap(); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// // Find the ToolBar -// expect(find.byType(ColorPickerToolbar), findsOneWidget); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 4th button is OK, since close is NOT last -// await $(ColorPickerToolbar).$(IconButton).at(3).tap(); -// expect(resultColor.value, Colors.red.value); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).at(3).tap(); -// // expect(resultColor.value, Colors.deepPurple.value); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 3rd button is Close, since close is NOT last -// await $(ColorPickerToolbar).$(IconButton).at(2).tap(); -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Expect no change in color -// expect(resultColor.value, Colors.red.value); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.6-icon: Patrol test dialog - custom labels, filledTonal-icons', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// platform: TargetPlatform.windows, -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: false, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// closeIsLast: false, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// dialogActionIcons: true, -// dialogCancelButtonLabel: 'CLOSER', -// dialogOkButtonLabel: 'USE', -// dialogOkButtonType: -// ColorPickerActionButtonType.filledTonal, -// dialogCancelButtonType: -// ColorPickerActionButtonType.filledTonal, -// dialogActionOrder: -// ColorPickerActionButtonOrder.adaptive, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// feedbackParseError: true, -// parseShortHexCode: true, -// ), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(2).tap(); -// // expect(resultColor.value, Colors.purple.value); -// expect(find.text('USE'), findsOneWidget); -// await $('USE').tap(); -// expect(Color(resultColor.value), Color(Colors.purple.value)); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// // Close via Cancel button -// expect(find.text('CLOSER'), findsOneWidget); -// await $('CLOSER').tap(); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// // Find the ToolBar -// expect(find.byType(ColorPickerToolbar), findsOneWidget); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 4th button is OK, since close is NOT last -// await $(ColorPickerToolbar).$(IconButton).at(3).tap(); -// expect(resultColor.value, Colors.red.value); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).at(3).tap(); -// // expect(resultColor.value, Colors.deepPurple.value); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 3rd button is Close, since close is NOT last -// await $(ColorPickerToolbar).$(IconButton).at(2).tap(); -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Expect no change in color -// expect(resultColor.value, Colors.red.value); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.7: Patrol test dialog - custom labels, elevated-no-icon, ' -// 'with constraints.', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// constraints: const BoxConstraints( -// minHeight: 480, minWidth: 320, maxWidth: 320), -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: false, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// // dialogActionOnlyOkButton: false, -// dialogCancelButtonLabel: 'CLOSE', -// dialogOkButtonLabel: 'Do', -// dialogOkButtonType: -// ColorPickerActionButtonType.elevated, -// dialogCancelButtonType: -// ColorPickerActionButtonType.elevated, -// dialogActionOrder: -// ColorPickerActionButtonOrder.okIsRight, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// feedbackParseError: true, -// parseShortHexCode: true, -// ), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(6).tap(); -// // expect(resultColor.value, Colors.lightBlue.value); -// expect(find.text('Do'), findsOneWidget); -// await $('Do').tap(); -// expect(Color(resultColor.value), Color(Colors.lightBlue.value)); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// // Close via Cancel button -// expect(find.text('CLOSE'), findsOneWidget); -// await $('CLOSE').tap(); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// // Find the ToolBar -// expect(find.byType(ColorPickerToolbar), findsOneWidget); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 4th button is Close, since close is last -// await $(ColorPickerToolbar).$(IconButton).at(3).tap(); -// expect(resultColor.value, Colors.lightBlue.value); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).at(3).tap(); -// // expect(resultColor.value, Colors.deepPurple.value); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 3rd button is OK, since close is NOT last -// await $(ColorPickerToolbar).$(IconButton).at(2).tap(); -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Expect no change in color -// expect(Color(resultColor.value), Color(Colors.deepPurple.value)); -// // Color(0xff673ab7); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.7-icon: Patrol test dialog - custom labels, elevated-icons, ' -// 'with constraints.', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// constraints: const BoxConstraints( -// minHeight: 480, minWidth: 320, maxWidth: 320), -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: false, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// dialogActionIcons: true, -// dialogCancelButtonLabel: 'CLOSE', -// dialogOkButtonLabel: 'Do', -// dialogOkButtonType: -// ColorPickerActionButtonType.elevated, -// dialogCancelButtonType: -// ColorPickerActionButtonType.elevated, -// dialogActionOrder: -// ColorPickerActionButtonOrder.okIsRight, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// feedbackParseError: true, -// parseShortHexCode: true, -// ), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(6).tap(); -// // expect(resultColor.value, Colors.lightBlue.value); -// expect(find.text('Do'), findsOneWidget); -// await $('Do').tap(); -// expect(Color(resultColor.value), Color(Colors.lightBlue.value)); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// // Close via Cancel button -// expect(find.text('CLOSE'), findsOneWidget); -// await $('CLOSE').tap(); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// // Find the ToolBar -// expect(find.byType(ColorPickerToolbar), findsOneWidget); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 4th button is Close, since close is last -// await $(ColorPickerToolbar).$(IconButton).at(3).tap(); -// expect(resultColor.value, Colors.lightBlue.value); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).at(3).tap(); -// // expect(resultColor.value, Colors.deepPurple.value); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 3rd button is OK, since close is NOT last -// await $(ColorPickerToolbar).$(IconButton).at(2).tap(); -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Expect no change in color -// expect(Color(resultColor.value), Color(Colors.deepPurple.value)); -// // Color(0xff673ab7); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.8: Patrol test dialog - custom labels, outlined-no-icon, ' -// 'with constraints and custom transition.', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// constraints: const BoxConstraints( -// minHeight: 480, minWidth: 320, maxWidth: 320), -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: true, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogCancelButtonLabel: 'CLOSE', -// dialogOkButtonLabel: 'OK', -// dialogOkButtonType: -// ColorPickerActionButtonType.outlined, -// dialogCancelButtonType: -// ColorPickerActionButtonType.outlined, -// dialogActionOrder: -// ColorPickerActionButtonOrder.okIsLeft, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// feedbackParseError: true, -// parseShortHexCode: true, -// ), -// transitionBuilder: (BuildContext context, -// Animation a1, -// Animation a2, -// Widget widget) { -// final double curvedValue = -// Curves.easeInOutBack.transform(a1.value) - 1.0; -// return Transform( -// transform: Matrix4.translationValues( -// 0.0, curvedValue * 200, 0.0), -// child: Opacity( -// opacity: a1.value, -// child: widget, -// ), -// ); -// }, -// transitionDuration: const Duration(milliseconds: 400), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(6).tap(); -// // expect(resultColor.value, Colors.lightBlue.value); -// expect(find.text('OK'), findsOneWidget); -// await $('OK').tap(); -// expect(Color(resultColor.value), Color(Colors.lightBlue.value)); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// // Find the ToolBar -// expect(find.byType(ColorPickerToolbar), findsOneWidget); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 4th button is Close, since close is last -// await $(ColorPickerToolbar).$(IconButton).at(3).tap(); -// expect(resultColor.value, Colors.lightBlue.value); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// // Close via Cancel button -// expect(find.text('CLOSE'), findsOneWidget); -// await $('CLOSE').tap(); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).at(3).tap(); -// // expect(resultColor.value, Colors.deepPurple.value); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 3rd button is OK, since close is NOT last -// await $(ColorPickerToolbar).$(IconButton).at(2).tap(); -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Expect no change in color -// expect(Color(resultColor.value), Color(Colors.deepPurple.value)); -// -// // Open dialog again -// await $('Open').tap(); -// // Got to wheel picker -// expect(find.text('Wheel'), findsOneWidget); -// await $('Wheel').tap(); -// // Tap the center of the wheel picker -// expect(find.byType(ColorWheelPicker), findsOneWidget); -// await $(ColorWheelPicker).tap(); -// // Tap close button -// expect(find.text('OK'), findsOneWidget); -// await $('OK').tap(); -// // We get a purple color from smack in the middle -// expect(Color(resultColor.value), const Color(0xff574080)); -// }, -// ); -// -// patrolWidgetTest( -// 'PAT1.8-icon: Patrol test dialog - custom labels, outlined-icon, ' -// 'with constraints and custom transition.', -// (PatrolTester $) async { -// Color resultColor = Colors.blue; -// await $.pumpWidgetAndSettle( -// TestPicker( -// widget: Builder( -// builder: (BuildContext context) { -// return ElevatedButton( -// onPressed: () async { -// resultColor = await showColorPickerDialog( -// context, -// resultColor, -// constraints: const BoxConstraints( -// minHeight: 480, minWidth: 320, maxWidth: 320), -// pickersEnabled: const { -// ColorPickerType.both: false, -// ColorPickerType.primary: true, -// ColorPickerType.accent: true, -// ColorPickerType.bw: false, -// ColorPickerType.custom: false, -// ColorPickerType.wheel: true, -// }, -// includeIndex850: true, -// crossAxisAlignment: CrossAxisAlignment.start, -// enableTonalPalette: true, -// enableOpacity: true, -// actionButtons: const ColorPickerActionButtons( -// okButton: true, -// closeButton: true, -// okTooltip: 'OK NOW', -// closeTooltip: 'CLOSE NOW', -// toolIconsThemeData: IconThemeData( -// color: Colors.red, -// size: 20, -// opacity: 0.88, -// ), -// visualDensity: VisualDensity.comfortable, -// padding: EdgeInsets.all(2), -// splashRadius: 20, -// dialogActionButtons: true, -// dialogActionIcons: true, -// dialogCancelButtonLabel: 'CLOSE', -// dialogOkButtonLabel: 'OK', -// dialogOkButtonType: -// ColorPickerActionButtonType.outlined, -// dialogCancelButtonType: -// ColorPickerActionButtonType.outlined, -// dialogActionOrder: -// ColorPickerActionButtonOrder.okIsLeft, -// ), -// copyPasteBehavior: const ColorPickerCopyPasteBehavior( -// copyButton: true, -// pasteButton: true, -// editFieldCopyButton: true, -// feedbackParseError: true, -// parseShortHexCode: true, -// ), -// transitionBuilder: (BuildContext context, -// Animation a1, -// Animation a2, -// Widget widget) { -// final double curvedValue = -// Curves.easeInOutBack.transform(a1.value) - 1.0; -// return Transform( -// transform: Matrix4.translationValues( -// 0.0, curvedValue * 200, 0.0), -// child: Opacity( -// opacity: a1.value, -// child: widget, -// ), -// ); -// }, -// transitionDuration: const Duration(milliseconds: 400), -// ); -// }, -// child: const Text('Open'), -// ); -// }, -// ), -// ), -// ); -// -// // Test primary color picker. -// expect(find.text('Open'), findsOneWidget); -// await $('Open').tap(); -// -// expect(find.text('Primary'), findsOneWidget); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// await $(ColorIndicator).at(6).tap(); -// // expect(resultColor.value, Colors.lightBlue.value); -// expect(find.text('OK'), findsOneWidget); -// await $('OK').tap(); -// expect(Color(resultColor.value), Color(Colors.lightBlue.value)); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).tap(); -// // expect(resultColor.value, Colors.red.value); -// // Find the ToolBar -// expect(find.byType(ColorPickerToolbar), findsOneWidget); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 4th button is Close, since close is last -// await $(ColorPickerToolbar).$(IconButton).at(3).tap(); -// expect(resultColor.value, Colors.lightBlue.value); -// -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Open dialog again -// await $('Open').tap(); -// // Close via Cancel button -// expect(find.text('CLOSE'), findsOneWidget); -// await $('CLOSE').tap(); -// -// // Open dialog again -// await $('Open').tap(); -// await $('Primary').tap(); -// await $(ColorIndicator).at(3).tap(); -// // expect(resultColor.value, Colors.deepPurple.value); -// // Find the ToolBar buttons, 4 of them configured. -// expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); -// // Close via toolbar, 3rd button is OK, since close is NOT last -// await $(ColorPickerToolbar).$(IconButton).at(2).tap(); -// // Dialog is closed -// expect(find.text('Open'), findsOneWidget); -// // Expect no change in color -// expect(Color(resultColor.value), Color(Colors.deepPurple.value)); -// -// // Open dialog again -// await $('Open').tap(); -// // Got to wheel picker -// expect(find.text('Wheel'), findsOneWidget); -// await $('Wheel').tap(); -// // Tap the center of the wheel picker -// expect(find.byType(ColorWheelPicker), findsOneWidget); -// await $(ColorWheelPicker).tap(); -// // Tap close button -// expect(find.text('OK'), findsOneWidget); -// await $('OK').tap(); -// // We get a purple color from smack in the middle -// expect(Color(resultColor.value), const Color(0xff574080)); -// }, -// ); -// -// ///--- -// }); -// } -// -// class TestPicker extends StatelessWidget { -// const TestPicker({super.key, required this.widget, this.platform}); -// final Widget widget; -// final TargetPlatform? platform; -// -// @override -// Widget build(BuildContext context) { -// debugDefaultTargetPlatformOverride = null; -// return MaterialApp( -// title: 'TestWidget', -// theme: ThemeData( -// platform: platform, -// ), -// home: Scaffold( -// appBar: AppBar( -// title: const Text('TestWidget'), -// ), -// body: SingleChildScrollView( -// child: widget, -// ), -// ), -// ); -// } -// } +// void main() {} + +import 'package:flex_color_picker/flex_color_picker.dart'; +import 'package:flex_color_picker/src/widgets/color_picker_toolbar.dart'; +import 'package:flex_color_picker/src/widgets/opacity/opacity_slider.dart'; +import 'package:flex_color_picker/src/widgets/recent_colors.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:patrol_finders/patrol_finders.dart'; + +// ignore_for_file: unnecessary_null_comparison + +//**************************************************************************** +// FlexColorPicker ColorPicker Widget tests +//**************************************************************************** +void main() { + const ValueKey testKey = ValueKey('test'); + + group('PAT1: Patrol Finder ColorPicker Tests', () { + debugDefaultTargetPlatformOverride = null; + + patrolWidgetTest( + 'PAT1.1: Patrol test finds correct primary and accent pickers and colors', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + widget: ColorPicker( + key: testKey, + onColorChanged: (Color color) { + resultColor = color; + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + expect(resultColor.value, Colors.purple.value); + await $(ColorIndicator).at(20).tap(); + expect(resultColor.value, Colors.purple[100]!.value); + + // Test accent color picker. + expect(find.text('Accent'), findsOneWidget); + await $('Accent').tap(); + await $(ColorIndicator).tap(); + expect(resultColor.value, Colors.redAccent.value); + await $(ColorIndicator).at(5).tap(); + expect(resultColor.value, Colors.blueAccent.value); + await $(ColorIndicator).at(18).tap(); + expect(resultColor.value, Colors.blueAccent[400]!.value); + }, + ); + + // + // ************************************************************************* + // + + patrolWidgetTest( + 'PAT1.2: Patrol test configured pickers and colors', + // config: PatrolTestConfig(findTimeout: const Duration(seconds: 10)), + (PatrolTester $) async { + Color resultColor = Colors.blue; + Color startColor = Colors.blue; + Color endColor = Colors.blue; + List recentColors = []; + + await $.pumpWidgetAndSettle( + TestPicker( + widget: ColorPicker( + key: testKey, + color: Colors.red, // Primary picker s default selected + onColorChanged: (Color color) { + resultColor = color; + }, + onColorChangeStart: (Color color) { + startColor = color; + }, + onColorChangeEnd: (Color color) { + endColor = color; + }, + pickersEnabled: const { + ColorPickerType.both: true, + ColorPickerType.primary: false, + ColorPickerType.accent: false, + ColorPickerType.bw: true, + ColorPickerType.custom: true, + ColorPickerType.customSecondary: true, + ColorPickerType.wheel: true, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: false, + dialogActionOnlyOkButton: true, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + ), + hasBorder: true, + borderRadius: 10, + borderColor: Colors.black, + wheelWidth: 32, + wheelSquarePadding: 4, + wheelSquareBorderRadius: 6, + wheelHasBorder: true, + title: const Text('Title'), + heading: const Text('Heading'), + subheading: const Text('Subheading'), + tonalSubheading: const Text('Tonal'), + wheelSubheading: const Text('Wheel heading'), + opacitySubheading: const Text('Opacity heading'), + recentColorsSubheading: const Text('Recent colors heading'), + showMaterialName: true, + showColorName: true, + showColorCode: true, + colorCodeHasColor: true, + showColorValue: true, + showRecentColors: true, + maxRecentColors: 4, + recentColors: recentColors, + onRecentColorsChanged: (List colors) { + recentColors = colors; + }, + selectedPickerTypeColor: Colors.white, + customColorSwatchesAndNames: , String>{ + ColorTools.createPrimarySwatch(const Color(0xFF6200EE)): + 'Guide Purple', + ColorTools.createPrimarySwatch(const Color(0xFF3700B3)): + 'Guide Purple Variant', + ColorTools.createAccentSwatch(const Color(0xFF03DAC6)): + 'Guide Teal', + }, + customSecondaryColorSwatchesAndNames: , + String>{ + ColorTools.createPrimarySwatch(const Color(0xFF00EE4B)): + 'Option 1', + ColorTools.createPrimarySwatch(const Color(0xFF92B300)): + 'Option 2', + }, + ), + ), + ); + + // We should NOT find the separated primary and accent pickers + expect(find.text('Primary'), findsNothing); + expect(find.text('Accent'), findsNothing); + // Test titles + expect(find.text('Title'), findsOneWidget); + expect(find.text('Heading'), findsOneWidget); + expect(find.text('Subheading'), findsOneWidget); + expect(find.text('Tonal'), findsOneWidget); + expect(find.text('Opacity heading'), findsOneWidget); + expect(find.text('Recent colors heading'), findsOneWidget); + + // Test primary & accent color picker. + expect(find.text('Primary & Accent'), findsOneWidget); + await $('Primary & Accent').tap(); + await $(ColorIndicator).at(1).tap(); + expect(startColor.value, Colors.red.value); + expect(endColor.value, Colors.redAccent.value); + expect(resultColor.value, Colors.redAccent.value); + // Test recent colors + expect(recentColors.contains(Color(Colors.red.value)), true); + await $(ColorIndicator).at(34).tap(); + expect(startColor.value, Colors.redAccent.value); + expect(endColor.value, Colors.grey.value); + expect(resultColor.value, Colors.grey.value); + // Test recent colors + expect(recentColors.contains(Color(Colors.red.value)), true); + expect(recentColors.contains(Color(Colors.redAccent.value)), true); + await $(ColorIndicator).at(44).tap(); + expect(startColor.value, Colors.grey.value); + expect(endColor.value, Colors.grey[850]!.value); + expect(resultColor.value, Colors.grey[850]!.value); + // Test recent colors + expect(recentColors.contains(Color(Colors.red.value)), true); + expect(recentColors.contains(Color(Colors.redAccent.value)), true); + expect(recentColors.contains(Color(Colors.grey.value)), true); + + // Test black & white color picker. + expect(find.text('Black & White'), findsOneWidget); + await $('Black & White').tap(); + // Black shade color test + await $(ColorIndicator).at(8).tap(); + expect(startColor.value, Colors.grey[850]!.value); + expect(endColor.value, ColorTools.blackShade[600]!.value); + expect(resultColor.value, ColorTools.blackShade[600]!.value); + // Test recent colors + expect(recentColors.contains(Color(Colors.red.value)), true); + expect(recentColors.contains(Color(Colors.redAccent.value)), true); + expect(recentColors.contains(Color(Colors.grey.value)), true); + expect(recentColors.contains(Color(Colors.grey[850]!.value)), true); + // White shade color test + await $(ColorIndicator).at(1).tap(); + expect(resultColor.value, ColorTools.whiteShade[500]!.value); + // Test recent colors + expect(recentColors.contains(Color(Colors.red.value)), + false); // 4 max, no red + expect(recentColors.contains(Color(Colors.redAccent.value)), true); + expect(recentColors.contains(Color(Colors.grey.value)), true); + expect(recentColors.contains(Color(Colors.grey[850]!.value)), true); + expect(recentColors.contains(Color(ColorTools.blackShade[600]!.value)), + true); + await $(ColorIndicator).at(2).tap(); + expect(resultColor, Colors.white); + await $(ColorIndicator).at(11).tap(); + expect(resultColor.value, ColorTools.whiteShade[900]!.value); + + // Test Custom color picker. + expect(find.text('Custom'), findsOneWidget); + await $('Custom').tap(); + await $(ColorIndicator).at(1).tap(); + expect(startColor.value, ColorTools.whiteShade[900]!.value); + expect(endColor, const Color(0xFF3700B3)); + expect(resultColor, const Color(0xFF3700B3)); + + // Test Option color picker. + expect(find.text('Option'), findsOneWidget); + await $('Option').tap(); + await $(ColorIndicator).at(1).tap(); + expect(startColor, const Color(0xFF3700B3)); + expect(endColor, const Color(0xFF92B300)); + expect(resultColor, const Color(0xFF92B300)); + + // Test Wheel color picker. + expect(find.text('Wheel'), findsOneWidget); + await $('Wheel').tap(); + expect(find.text('Wheel heading'), findsOneWidget); + expect(find.text('Tonal'), findsOneWidget); + // The 10th ColorIndicator will be first tonal and always black. + await $(ColorIndicator).at(10).tap(); + expect(startColor, const Color(0xFF92B300)); + expect(endColor, Colors.black); + expect(resultColor, Colors.black); + await $(ColorIndicator).at(16).tap(); + expect(startColor, Colors.black); + expect(endColor, const Color(0xFF688000)); + expect(resultColor, const Color(0xFF688000)); + // Find the ColorWheelPicker + expect(find.byType(ColorWheelPicker), findsOneWidget); + // Tap center of the ColorWheelPicker + await $(ColorWheelPicker).tap(); + expect(resultColor, const Color(0xff748040)); + + // The 24th ColorIndicator will be last tonal and always white. + await $(ColorIndicator).at(24).tap(); + expect(resultColor, Colors.white); + + // Find the RecentColors + expect(find.byType(RecentColors), findsOneWidget); + // Recent colors has 4 color indicators, since we set max to 4. + expect($(RecentColors).$(ColorIndicator), findsNWidgets(4)); + // Let's tap the last one, we need to scroll to it first. + await $(RecentColors).$(ColorIndicator).at(3).scrollTo().tap(); + // Result should be 5 result color from earlier above. + expect(resultColor, const Color(0xff92b300)); + + // Find the OpacitySlider + // TODO(rydmike): Get the slider test working! + expect(find.byType(OpacitySlider), findsOneWidget); + // expect(find.byType(Slider), findsOneWidget); + // Tap center of the OpacitySlider + // await $(OpacitySlider) + // .scrollTo(settlePolicy: SettlePolicy.trySettle) + // .tap(); + + // Find the Text entry + expect(find.byType(ColorCodeField), findsOneWidget); + expect(find.byType(TextField), findsOneWidget); + // TODO(rydmike): Get the color code entry test working! + // await $(find.byType(TextField)).enterText('613E42'); + // await $(find.byType(ColorCodeField)).enterText('613E42'); + // expect(resultColor, const Color(0xFF613E42)); + + // Find the ToolBar + expect(find.byType(ColorPickerToolbar), findsOneWidget); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Copy the Color + await $(ColorPickerToolbar).$(IconButton).at(0).tap( + settlePolicy: SettlePolicy.trySettle, + visibleTimeout: const Duration(seconds: 1), + settleTimeout: const Duration(seconds: 2), + ); + // TODO(rydmike): Figure out how to test clipboard copy/paste. + // We should have some clipboard data from above tap. But the below + // attempt to get the data never completes. The code flow hit paths + // from above also indicates the buffer is empty after the tap above. + // final ClipboardData? clipData = + // await Clipboard.getData(Clipboard.kTextPlain); + // debugPrint('Clip data: $clipData'); + + // TEST COPY/PASTE via toolbar buttons + // Go to another tab select a new color + await $('Primary & Accent').tap(); + await $(ColorIndicator).at(1).tap(); + expect(resultColor.value, Colors.redAccent.value); + // Copy in the redAccent color + await $(ColorPickerToolbar).$(IconButton).at(0).tap( + settlePolicy: SettlePolicy.trySettle, + visibleTimeout: const Duration(seconds: 1), + settleTimeout: const Duration(seconds: 2), + ); + // Select pink color + await $(ColorIndicator).at(2).tap(); + expect(resultColor.value, Colors.pink.value); + // Paste in the red accent value color + await $(ColorPickerToolbar).$(IconButton).at(1).tap( + settlePolicy: SettlePolicy.trySettle, + visibleTimeout: const Duration(seconds: 1), + settleTimeout: const Duration(seconds: 2), + ); + // This is the color we should find but do not since copy did nothing. + // The paste wont work either. + // expect(Color(resultColor.value), Color(Colors.redAccent.value)); + // Color(0xffe91e63); + }, + ); + + // Test issue https://github.com/rydmike/flex_color_picker/issues/71 + patrolWidgetTest( + 'PAT1.3: Patrol widget test for issue #71 ', + (PatrolTester $) async { + Color resultColor = const Color(0xFF613E42); + await $.pumpWidgetAndSettle( + TestPicker( + widget: ColorPicker( + key: testKey, + color: resultColor, + enableTonalPalette: true, + onColorChanged: (Color color) { + resultColor = color; + }, + width: 40, + height: 40, + borderRadius: 4, + spacing: 5, + runSpacing: 5, + wheelDiameter: 155, + showMaterialName: true, + showColorName: true, + showColorCode: true, + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: true, + ColorPickerType.wheel: true, + }, + actionButtons: const ColorPickerActionButtons( + okButton: false, + closeButton: true, + okTooltip: 'DO', + closeTooltipIsClose: false, + toolIconsThemeData: IconThemeData( + color: Colors.blue, + size: 20, + opacity: 0.95, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + dialogActionOnlyOkButton: true, + ), + ), + ), + ); + + // Test primary color picker. + expect(find.text('Primary'), findsOneWidget); + expect(find.text('Accent'), findsOneWidget); + expect(find.text('Custom'), findsNothing); // We gave no custom colors + expect(find.text('Wheel'), findsOneWidget); + + // Find the ColorWheelPicker, we are on it by default + expect(find.byType(ColorWheelPicker), findsOneWidget); + // Tap sliding selector on wheel + await $('Wheel').tap(); + + // The 14th ColorIndicator will be 5th tonal + await $(ColorIndicator).at(14).tap(); + expect(resultColor, const Color(0xFF7D2939)); + + // Tap primary slider, no crash! This crashed without the FIX for #71 + await $('Primary').tap(); + // Tap a Material red shade color + await $(ColorIndicator).at(22).tap(); + expect(resultColor.value, Colors.red[300]!.value); + }, + ); + + patrolWidgetTest( + 'PAT1.4: Patrol test dialog - default labels, text buttons-no-icons', + (PatrolTester $) async { + Color resultColor = Colors.orange; + await $.pumpWidgetAndSettle( + TestPicker( + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: false, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + // dialogActionOnlyOkButton: false, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + ), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + // expect(resultColor.value, Colors.purple.value); + await $(ColorIndicator).at(20).tap(); + // expect(resultColor.value, Colors.purple[100]!.value); + + // Test accent color picker. + expect(find.text('Accent'), findsOneWidget); + await $('Accent').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.redAccent.value); + await $(ColorIndicator).at(5).tap(); + // expect(resultColor.value, Colors.blueAccent.value); + await $(ColorIndicator).at(18).tap(); + + expect(find.byType(TextButton), findsExactly(2)); + await $(TextButton).at(1).tap(); + expect(Color(resultColor.value), Color(Colors.blueAccent[400]!.value)); + const Color(0xff2979ff); + const Color(0xffff9800); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + // expect(resultColor.value, Colors.purple.value); + expect(find.text('OK'), findsOneWidget); + await $('OK').tap(); + expect(resultColor.value, Colors.purple.value); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + expect(find.text('Cancel'), findsOneWidget); + await $('Cancel').tap(); + expect(resultColor.value, Colors.purple.value); + }, + ); + + patrolWidgetTest( + 'PAT1.4-icons: Patrol test dialog - default labels, text buttons-icons', + (PatrolTester $) async { + Color resultColor = Colors.orange; + await $.pumpWidgetAndSettle( + TestPicker( + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: false, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionIcons: true, + dialogActionButtons: true, + // dialogActionOnlyOkButton: false, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + ), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + // expect(resultColor.value, Colors.purple.value); + await $(ColorIndicator).at(20).tap(); + // expect(resultColor.value, Colors.purple[100]!.value); + + // Test accent color picker. + expect(find.text('Accent'), findsOneWidget); + await $('Accent').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.redAccent.value); + await $(ColorIndicator).at(5).tap(); + // expect(resultColor.value, Colors.blueAccent.value); + await $(ColorIndicator).at(18).tap(); + + expect(find.text('OK'), findsOneWidget); + await $('OK').tap(); + expect(Color(resultColor.value), Color(Colors.blueAccent[400]!.value)); + const Color(0xff2979ff); + const Color(0xffff9800); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + // expect(resultColor.value, Colors.purple.value); + expect(find.text('OK'), findsOneWidget); + await $('OK').tap(); + expect(resultColor.value, Colors.purple.value); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + expect(find.text('Cancel'), findsOneWidget); + await $('Cancel').tap(); + expect(resultColor.value, Colors.purple.value); + }, + ); + + patrolWidgetTest( + 'PAT1.5: Patrol test dialog - custom labels, filled buttons-no-icons', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: false, + }, + columnSpacing: 4, + toolbarSpacing: 0, + shadesSpacing: 0, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + // dialogActionOnlyOkButton: false, + dialogCancelButtonLabel: 'CLOSE', + dialogOkButtonLabel: 'USE', + dialogOkButtonType: ColorPickerActionButtonType.filled, + dialogCancelButtonType: + ColorPickerActionButtonType.filled, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + feedbackParseError: true, + parseShortHexCode: true, + ), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + // expect(resultColor.value, Colors.purple.value); + expect(find.text('USE'), findsOneWidget); + await $('USE').tap(); + expect(Color(resultColor.value), Color(Colors.purple.value)); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + expect(find.text('CLOSE'), findsOneWidget); + await $('CLOSE').tap(); + expect(resultColor.value, Colors.purple.value); + }, + ); + + patrolWidgetTest( + 'PAT1.5-icon: Patrol test dialog - custom labels, filled buttons-icons', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: false, + }, + columnSpacing: 4, + toolbarSpacing: 0, + shadesSpacing: 0, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + // dialogActionOnlyOkButton: false, + dialogCancelButtonLabel: 'CLOSE', + dialogOkButtonLabel: 'USE', + dialogActionIcons: true, + dialogOkButtonType: ColorPickerActionButtonType.filled, + dialogCancelButtonType: + ColorPickerActionButtonType.filled, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + feedbackParseError: true, + parseShortHexCode: true, + ), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + // expect(resultColor.value, Colors.purple.value); + expect(find.text('USE'), findsOneWidget); + await $('USE').tap(); + expect(Color(resultColor.value), Color(Colors.purple.value)); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + expect(find.text('CLOSE'), findsOneWidget); + await $('CLOSE').tap(); + expect(resultColor.value, Colors.purple.value); + }, + ); + + patrolWidgetTest( + 'PAT1.6: Patrol test dialog - custom labels, filledTonal-no-icons', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + platform: TargetPlatform.windows, + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: false, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + closeIsLast: false, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + dialogCancelButtonLabel: 'CLOSER', + dialogOkButtonLabel: 'USE', + dialogOkButtonType: + ColorPickerActionButtonType.filledTonal, + dialogCancelButtonType: + ColorPickerActionButtonType.filledTonal, + dialogActionOrder: + ColorPickerActionButtonOrder.adaptive, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + feedbackParseError: true, + parseShortHexCode: true, + ), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + // expect(resultColor.value, Colors.purple.value); + expect(find.text('USE'), findsOneWidget); + await $('USE').tap(); + expect(Color(resultColor.value), Color(Colors.purple.value)); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + // Close via Cancel button + expect(find.text('CLOSER'), findsOneWidget); + await $('CLOSER').tap(); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + // Find the ToolBar + expect(find.byType(ColorPickerToolbar), findsOneWidget); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 4th button is OK, since close is NOT last + await $(ColorPickerToolbar).$(IconButton).at(3).tap(); + expect(resultColor.value, Colors.red.value); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).at(3).tap(); + // expect(resultColor.value, Colors.deepPurple.value); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 3rd button is Close, since close is NOT last + await $(ColorPickerToolbar).$(IconButton).at(2).tap(); + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Expect no change in color + expect(resultColor.value, Colors.red.value); + }, + ); + + patrolWidgetTest( + 'PAT1.6-icon: Patrol test dialog - custom labels, filledTonal-icons', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + platform: TargetPlatform.windows, + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: false, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + closeIsLast: false, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + dialogActionIcons: true, + dialogCancelButtonLabel: 'CLOSER', + dialogOkButtonLabel: 'USE', + dialogOkButtonType: + ColorPickerActionButtonType.filledTonal, + dialogCancelButtonType: + ColorPickerActionButtonType.filledTonal, + dialogActionOrder: + ColorPickerActionButtonOrder.adaptive, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + feedbackParseError: true, + parseShortHexCode: true, + ), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(2).tap(); + // expect(resultColor.value, Colors.purple.value); + expect(find.text('USE'), findsOneWidget); + await $('USE').tap(); + expect(Color(resultColor.value), Color(Colors.purple.value)); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + // Close via Cancel button + expect(find.text('CLOSER'), findsOneWidget); + await $('CLOSER').tap(); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + // Find the ToolBar + expect(find.byType(ColorPickerToolbar), findsOneWidget); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 4th button is OK, since close is NOT last + await $(ColorPickerToolbar).$(IconButton).at(3).tap(); + expect(resultColor.value, Colors.red.value); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).at(3).tap(); + // expect(resultColor.value, Colors.deepPurple.value); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 3rd button is Close, since close is NOT last + await $(ColorPickerToolbar).$(IconButton).at(2).tap(); + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Expect no change in color + expect(resultColor.value, Colors.red.value); + }, + ); + + patrolWidgetTest( + 'PAT1.7: Patrol test dialog - custom labels, elevated-no-icon, ' + 'with constraints.', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + constraints: const BoxConstraints( + minHeight: 480, minWidth: 320, maxWidth: 320), + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: false, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + // dialogActionOnlyOkButton: false, + dialogCancelButtonLabel: 'CLOSE', + dialogOkButtonLabel: 'Do', + dialogOkButtonType: + ColorPickerActionButtonType.elevated, + dialogCancelButtonType: + ColorPickerActionButtonType.elevated, + dialogActionOrder: + ColorPickerActionButtonOrder.okIsRight, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + feedbackParseError: true, + parseShortHexCode: true, + ), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(6).tap(); + // expect(resultColor.value, Colors.lightBlue.value); + expect(find.text('Do'), findsOneWidget); + await $('Do').tap(); + expect(Color(resultColor.value), Color(Colors.lightBlue.value)); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + // Close via Cancel button + expect(find.text('CLOSE'), findsOneWidget); + await $('CLOSE').tap(); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + // Find the ToolBar + expect(find.byType(ColorPickerToolbar), findsOneWidget); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 4th button is Close, since close is last + await $(ColorPickerToolbar).$(IconButton).at(3).tap(); + expect(resultColor.value, Colors.lightBlue.value); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).at(3).tap(); + // expect(resultColor.value, Colors.deepPurple.value); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 3rd button is OK, since close is NOT last + await $(ColorPickerToolbar).$(IconButton).at(2).tap(); + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Expect no change in color + expect(Color(resultColor.value), Color(Colors.deepPurple.value)); + // Color(0xff673ab7); + }, + ); + + patrolWidgetTest( + 'PAT1.7-icon: Patrol test dialog - custom labels, elevated-icons, ' + 'with constraints.', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + constraints: const BoxConstraints( + minHeight: 480, minWidth: 320, maxWidth: 320), + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: false, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + dialogActionIcons: true, + dialogCancelButtonLabel: 'CLOSE', + dialogOkButtonLabel: 'Do', + dialogOkButtonType: + ColorPickerActionButtonType.elevated, + dialogCancelButtonType: + ColorPickerActionButtonType.elevated, + dialogActionOrder: + ColorPickerActionButtonOrder.okIsRight, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + feedbackParseError: true, + parseShortHexCode: true, + ), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(6).tap(); + // expect(resultColor.value, Colors.lightBlue.value); + expect(find.text('Do'), findsOneWidget); + await $('Do').tap(); + expect(Color(resultColor.value), Color(Colors.lightBlue.value)); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + // Close via Cancel button + expect(find.text('CLOSE'), findsOneWidget); + await $('CLOSE').tap(); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + // Find the ToolBar + expect(find.byType(ColorPickerToolbar), findsOneWidget); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 4th button is Close, since close is last + await $(ColorPickerToolbar).$(IconButton).at(3).tap(); + expect(resultColor.value, Colors.lightBlue.value); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).at(3).tap(); + // expect(resultColor.value, Colors.deepPurple.value); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 3rd button is OK, since close is NOT last + await $(ColorPickerToolbar).$(IconButton).at(2).tap(); + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Expect no change in color + expect(Color(resultColor.value), Color(Colors.deepPurple.value)); + // Color(0xff673ab7); + }, + ); + + patrolWidgetTest( + 'PAT1.8: Patrol test dialog - custom labels, outlined-no-icon, ' + 'with constraints and custom transition.', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + constraints: const BoxConstraints( + minHeight: 480, minWidth: 320, maxWidth: 320), + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: true, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogCancelButtonLabel: 'CLOSE', + dialogOkButtonLabel: 'OK', + dialogOkButtonType: + ColorPickerActionButtonType.outlined, + dialogCancelButtonType: + ColorPickerActionButtonType.outlined, + dialogActionOrder: + ColorPickerActionButtonOrder.okIsLeft, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + feedbackParseError: true, + parseShortHexCode: true, + ), + transitionBuilder: (BuildContext context, + Animation a1, + Animation a2, + Widget widget) { + final double curvedValue = + Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: Matrix4.translationValues( + 0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: widget, + ), + ); + }, + transitionDuration: const Duration(milliseconds: 400), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(6).tap(); + // expect(resultColor.value, Colors.lightBlue.value); + expect(find.text('OK'), findsOneWidget); + await $('OK').tap(); + expect(Color(resultColor.value), Color(Colors.lightBlue.value)); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + // Find the ToolBar + expect(find.byType(ColorPickerToolbar), findsOneWidget); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 4th button is Close, since close is last + await $(ColorPickerToolbar).$(IconButton).at(3).tap(); + expect(resultColor.value, Colors.lightBlue.value); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + // Close via Cancel button + expect(find.text('CLOSE'), findsOneWidget); + await $('CLOSE').tap(); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).at(3).tap(); + // expect(resultColor.value, Colors.deepPurple.value); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 3rd button is OK, since close is NOT last + await $(ColorPickerToolbar).$(IconButton).at(2).tap(); + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Expect no change in color + expect(Color(resultColor.value), Color(Colors.deepPurple.value)); + + // Open dialog again + await $('Open').tap(); + // Got to wheel picker + expect(find.text('Wheel'), findsOneWidget); + await $('Wheel').tap(); + // Tap the center of the wheel picker + expect(find.byType(ColorWheelPicker), findsOneWidget); + await $(ColorWheelPicker).tap(); + // Tap close button + expect(find.text('OK'), findsOneWidget); + await $('OK').tap(); + // We get a purple color from smack in the middle + expect(Color(resultColor.value), const Color(0xff574080)); + }, + ); + + patrolWidgetTest( + 'PAT1.8-icon: Patrol test dialog - custom labels, outlined-icon, ' + 'with constraints and custom transition.', + (PatrolTester $) async { + Color resultColor = Colors.blue; + await $.pumpWidgetAndSettle( + TestPicker( + widget: Builder( + builder: (BuildContext context) { + return ElevatedButton( + onPressed: () async { + resultColor = await showColorPickerDialog( + context, + resultColor, + constraints: const BoxConstraints( + minHeight: 480, minWidth: 320, maxWidth: 320), + pickersEnabled: const { + ColorPickerType.both: false, + ColorPickerType.primary: true, + ColorPickerType.accent: true, + ColorPickerType.bw: false, + ColorPickerType.custom: false, + ColorPickerType.wheel: true, + }, + includeIndex850: true, + crossAxisAlignment: CrossAxisAlignment.start, + enableTonalPalette: true, + enableOpacity: true, + actionButtons: const ColorPickerActionButtons( + okButton: true, + closeButton: true, + okTooltip: 'OK NOW', + closeTooltip: 'CLOSE NOW', + toolIconsThemeData: IconThemeData( + color: Colors.red, + size: 20, + opacity: 0.88, + ), + visualDensity: VisualDensity.comfortable, + padding: EdgeInsets.all(2), + splashRadius: 20, + dialogActionButtons: true, + dialogActionIcons: true, + dialogCancelButtonLabel: 'CLOSE', + dialogOkButtonLabel: 'OK', + dialogOkButtonType: + ColorPickerActionButtonType.outlined, + dialogCancelButtonType: + ColorPickerActionButtonType.outlined, + dialogActionOrder: + ColorPickerActionButtonOrder.okIsLeft, + ), + copyPasteBehavior: const ColorPickerCopyPasteBehavior( + copyButton: true, + pasteButton: true, + editFieldCopyButton: true, + feedbackParseError: true, + parseShortHexCode: true, + ), + transitionBuilder: (BuildContext context, + Animation a1, + Animation a2, + Widget widget) { + final double curvedValue = + Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: Matrix4.translationValues( + 0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: widget, + ), + ); + }, + transitionDuration: const Duration(milliseconds: 400), + ); + }, + child: const Text('Open'), + ); + }, + ), + ), + ); + + // Test primary color picker. + expect(find.text('Open'), findsOneWidget); + await $('Open').tap(); + + expect(find.text('Primary'), findsOneWidget); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + await $(ColorIndicator).at(6).tap(); + // expect(resultColor.value, Colors.lightBlue.value); + expect(find.text('OK'), findsOneWidget); + await $('OK').tap(); + expect(Color(resultColor.value), Color(Colors.lightBlue.value)); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).tap(); + // expect(resultColor.value, Colors.red.value); + // Find the ToolBar + expect(find.byType(ColorPickerToolbar), findsOneWidget); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 4th button is Close, since close is last + await $(ColorPickerToolbar).$(IconButton).at(3).tap(); + expect(resultColor.value, Colors.lightBlue.value); + + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Open dialog again + await $('Open').tap(); + // Close via Cancel button + expect(find.text('CLOSE'), findsOneWidget); + await $('CLOSE').tap(); + + // Open dialog again + await $('Open').tap(); + await $('Primary').tap(); + await $(ColorIndicator).at(3).tap(); + // expect(resultColor.value, Colors.deepPurple.value); + // Find the ToolBar buttons, 4 of them configured. + expect($(ColorPickerToolbar).$(IconButton), findsNWidgets(4)); + // Close via toolbar, 3rd button is OK, since close is NOT last + await $(ColorPickerToolbar).$(IconButton).at(2).tap(); + // Dialog is closed + expect(find.text('Open'), findsOneWidget); + // Expect no change in color + expect(Color(resultColor.value), Color(Colors.deepPurple.value)); + + // Open dialog again + await $('Open').tap(); + // Got to wheel picker + expect(find.text('Wheel'), findsOneWidget); + await $('Wheel').tap(); + // Tap the center of the wheel picker + expect(find.byType(ColorWheelPicker), findsOneWidget); + await $(ColorWheelPicker).tap(); + // Tap close button + expect(find.text('OK'), findsOneWidget); + await $('OK').tap(); + // We get a purple color from smack in the middle + expect(Color(resultColor.value), const Color(0xff574080)); + }, + ); + + ///--- + }); +} + +class TestPicker extends StatelessWidget { + const TestPicker({super.key, required this.widget, this.platform}); + final Widget widget; + final TargetPlatform? platform; + + @override + Widget build(BuildContext context) { + debugDefaultTargetPlatformOverride = null; + return MaterialApp( + title: 'TestWidget', + theme: ThemeData( + platform: platform, + ), + home: Scaffold( + appBar: AppBar( + title: const Text('TestWidget'), + ), + body: SingleChildScrollView( + child: widget, + ), + ), + ); + } +}