├── .github └── workflows │ └── main.yml ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assets ├── github_large_preview.png ├── original.png ├── readme.png ├── sample_preview.png └── try_here.png ├── example ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── ic_launcher-playstore.png │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ └── ic_launcher.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── color_output.dart │ ├── main.dart │ └── preview │ │ ├── chat_preview.dart │ │ └── social_preview.dart ├── pubspec.lock ├── pubspec.yaml ├── test │ └── widget_test.dart └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ └── Icon-512.png │ ├── index.html │ └── manifest.json ├── lib ├── color_blindness.dart ├── color_blindness_color_scheme.dart └── color_blindness_contrast_checker.dart ├── pubspec.lock ├── pubspec.yaml └── test └── color_blindness_color_scheme_test.dart /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v3 11 | - uses: subosito/flutter-action@v2 12 | with: 13 | channel: 'stable' # or: 'beta' or 'master' 14 | - run: flutter config --enable-web 15 | - run: flutter pub get 16 | - run: flutter test 17 | - run: | 18 | cd example/ 19 | flutter pub get 20 | flutter build web --release 21 | git clone --single-branch "https://${{ secrets.PAT }}@github.com/bernaferrari/bernaferrari.github.io.git" "clone_dir" 22 | rm -rf clone_dir/ColorBlindnessFlutter 23 | cp -r build/web clone_dir/ColorBlindnessFlutter 24 | cd clone_dir 25 | git config user.name github-actions 26 | git config user.email github-actions@github.com 27 | git add * 28 | git commit -m "generate ColorBlindnessFlutter" 29 | git push 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: d1178ae73b0a38c7e0f88416674a060c78d31849 8 | channel: master 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.2.0] - 10/05/2024 2 | 3 | * Update constraints to Flutter 3.22. 4 | * Support new ColorScheme colors. 5 | 6 | ## [0.1.2] - 03/03/2023 7 | 8 | * Update constraints to Flutter 2.19. 9 | 10 | ## [0.1.1] - 12/05/2022 11 | 12 | * Add support for M3 Color Scheme (Flutter 3). 13 | 14 | ## [0.1.0] - 23/02/2021 15 | 16 | * Add null safety. 17 | 18 | ## [0.0.1] - 04/10/2020 19 | 20 | * Initial release. 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020 Bernardo Ferrari 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Image of Color Blindness on Flutter](https://github.com/bernaferrari/ColorBlindnessFlutter/raw/main/assets/readme.png) 2 | 3 | # Color Blindness on Flutter 4 | 5 | Every app has colors. How to make sure they are accessible? 6 | How to avoid accessibility issues as other people in the same project start to change the Color Scheme? 7 | This is a Flutter plugin that can: 8 | 9 | 1. Change the whole theme, by wrapping a ColorScheme with `colorBlindnessColorScheme()`. 10 | 2. Be used in CI tests, with `colorBlindnessAssertContrast()`. 11 | 3. Be used to modify a single color. 12 | 13 | The main idea is for you to (temporarily) wrap your `ColorScheme()` into a `colorBlindnessColorScheme()` with a `ColorBlindnessType` as the secondary parameter. 14 | Doing so, it will simulate color blindness by modifying **ALL** ColorScheme colors. 15 | Then, you may change the type parameter and hot refresh/restart the app to see how it looks under different eyes. 16 | 17 | The interactive sample allows you to see how it works: 18 | 19 | 20 | 21 | [![Color Blindness on Flutter sample](https://github.com/bernaferrari/ColorBlindnessFlutter/raw/main/assets/sample_preview.png)](https://bernaferrari.github.io/ColorBlindnessFlutter/) 22 | 23 | ## Usage 24 | 25 | In the `pubspec.yaml` of your flutter project, add the following dependency: 26 | 27 | [![pub package](https://img.shields.io/pub/v/color_blindness.svg)](https://pub.dev/packages/color_blindness) 28 | 29 | ```yaml 30 | dependencies: 31 | color_blindness: ^VERSION 32 | ``` 33 | ### Color Scheme 34 | 35 | In your project, just wrap the `ColorScheme.dark(...)` with `colorBlindnessColorScheme()`. 36 | 37 | ```dart 38 | import 'package:color_blindness/color_blindness.dart'; 39 | 40 | Theme( 41 | data: ThemeData( 42 | colorScheme: colorBlindnessColorScheme(ColorScheme.dark(), ColorBlindnessType.tritanopia), 43 | ), 44 | child: MyApp(), 45 | ) 46 | ``` 47 | ### CI 48 | You can add a test to make sure the ColorScheme is always accessible. 49 | The second parameter is the WCAG minimum threshold, which is usually at least 4.5. 50 | 51 | ```dart 52 | colorScheme = ColorScheme.light( 53 | primary: const Color(0xff9f0042), 54 | secondary: const Color(0xff1e6100), 55 | ); 56 | expect(() => colorBlindnessAssertContrast(colorScheme, 4.0), returnsNormally); 57 | ``` 58 | 59 | ### Single Color 60 | You can either use `colorBlindness()` with `ColorBlindnessType` as the secondary parameter, or call the methods individually. 61 | 62 | ```dart 63 | const primary = const Color(0xff9f0042); 64 | // indirect way 65 | colorBlindness(primary, ColorBlindnessType.tritanopia); 66 | 67 | // direct way 68 | tritanopia(primary); 69 | ``` 70 | 71 | ## Reasoning 72 | This started in my [Color Studio project](https://github.com/bernaferrari/color-studio). There, you can preview different color blindness in different themes. 73 | However, I saw the possibility of contribution for those already using ColorScheme in an existing app. 74 | Similar to [RandomColorScheme](https://github.com/bernaferrari/RandomColorScheme), this may reach deeper places than Color Studio ever will. 75 | Also, there were ZERO packages in pub.dev related to color blindness, so this was the first one. 76 | The color blindness calculation was retrieved from [ColorBlinds](https://github.com/jordidekock/Colorblinds) project. 77 | 78 | ## Function listing 79 | - `colorBlindnessColorScheme(scheme: ColorScheme, type: ColorBlindnessType): ColorScheme` 80 | - `colorBlindnessAssertContrast(scheme: ColorScheme, minThreshold: double = 4.5)` 81 | - `colorBlindness(color: Color, type: ColorBlindnessType): Color` 82 | - `protanomaly(color: Color): Color` 83 | - `deuteranomaly(color: Color): Color` 84 | - `tritanomaly(color: Color): Color` 85 | - `protanopia(color: Color): Color` 86 | - `deuteranopia(color: Color): Color` 87 | - `tritanopia(color: Color): Color` 88 | - `achromatopsia(color: Color): Color` 89 | - `achromatomaly(color: Color): Color` 90 | 91 | `enum ColorBlindnessType { none, protanomaly, deuteranomaly, tritanomaly, protanopia, deuteranopia, tritanopia, achromatopsia, achromatomaly }` 92 | ## Reporting Issues 93 | 94 | If you have any suggestions or feedback, issues and pull requests are welcome. 95 | You can report [here](https://github.com/bernaferrari/ColorBlindnessFlutter/issues). 96 | 97 | ## License 98 | 99 | Copyright 2020 Bernardo Ferrari 100 | 101 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 102 | 103 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 104 | 105 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /assets/github_large_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/assets/github_large_preview.png -------------------------------------------------------------------------------- /assets/original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/assets/original.png -------------------------------------------------------------------------------- /assets/readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/assets/readme.png -------------------------------------------------------------------------------- /assets/sample_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/assets/sample_preview.png -------------------------------------------------------------------------------- /assets/try_here.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/assets/try_here.png -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: d1178ae73b0a38c7e0f88416674a060c78d31849 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Color Blindness on Flutter Sample 2 | 3 | This is the sample for the Color Blindness on Flutter library. Check the full documentation [here](https://github.com/bernaferrari/ColorBlindnessFlutter). 4 | 5 | 6 | 7 | [![Color Blindness on Flutter](../assets/sample_preview.png)](https://bernaferrari.github.io/ColorBlindnessFlutter/) 8 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | linter: 4 | rules: 5 | avoid_print: false # Uncomment to disable the `avoid_print` rule 6 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 7 | 8 | # Additional information about this file can be found at 9 | # https://dart.dev/guides/language/analysis-options 10 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 29 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.example" 42 | minSdkVersion 16 43 | targetSdkVersion 29 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /example/android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | FRAMEWORK_SEARCH_PATHS = ( 293 | "$(inherited)", 294 | "$(PROJECT_DIR)/Flutter", 295 | ); 296 | INFOPLIST_FILE = Runner/Info.plist; 297 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 298 | LIBRARY_SEARCH_PATHS = ( 299 | "$(inherited)", 300 | "$(PROJECT_DIR)/Flutter", 301 | ); 302 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 305 | SWIFT_VERSION = 5.0; 306 | VERSIONING_SYSTEM = "apple-generic"; 307 | }; 308 | name = Profile; 309 | }; 310 | 97C147031CF9000F007C117D /* Debug */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 316 | CLANG_CXX_LIBRARY = "libc++"; 317 | CLANG_ENABLE_MODULES = YES; 318 | CLANG_ENABLE_OBJC_ARC = YES; 319 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 320 | CLANG_WARN_BOOL_CONVERSION = YES; 321 | CLANG_WARN_COMMA = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INFINITE_RECURSION = YES; 328 | CLANG_WARN_INT_CONVERSION = YES; 329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_STRICT_PROTOTYPES = YES; 335 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 336 | CLANG_WARN_UNREACHABLE_CODE = YES; 337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 339 | COPY_PHASE_STRIP = NO; 340 | DEBUG_INFORMATION_FORMAT = dwarf; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | ENABLE_TESTABILITY = YES; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_DYNAMIC_NO_PIC = NO; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_OPTIMIZATION_LEVEL = 0; 347 | GCC_PREPROCESSOR_DEFINITIONS = ( 348 | "DEBUG=1", 349 | "$(inherited)", 350 | ); 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 358 | MTL_ENABLE_DEBUG_INFO = YES; 359 | ONLY_ACTIVE_ARCH = YES; 360 | SDKROOT = iphoneos; 361 | TARGETED_DEVICE_FAMILY = "1,2"; 362 | }; 363 | name = Debug; 364 | }; 365 | 97C147041CF9000F007C117D /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | ALWAYS_SEARCH_USER_PATHS = NO; 369 | CLANG_ANALYZER_NONNULL = YES; 370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 371 | CLANG_CXX_LIBRARY = "libc++"; 372 | CLANG_ENABLE_MODULES = YES; 373 | CLANG_ENABLE_OBJC_ARC = YES; 374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_COMMA = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_EMPTY_BODY = YES; 381 | CLANG_WARN_ENUM_CONVERSION = YES; 382 | CLANG_WARN_INFINITE_RECURSION = YES; 383 | CLANG_WARN_INT_CONVERSION = YES; 384 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 385 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 386 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 389 | CLANG_WARN_STRICT_PROTOTYPES = YES; 390 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 391 | CLANG_WARN_UNREACHABLE_CODE = YES; 392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 393 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 394 | COPY_PHASE_STRIP = NO; 395 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 396 | ENABLE_NS_ASSERTIONS = NO; 397 | ENABLE_STRICT_OBJC_MSGSEND = YES; 398 | GCC_C_LANGUAGE_STANDARD = gnu99; 399 | GCC_NO_COMMON_BLOCKS = YES; 400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 402 | GCC_WARN_UNDECLARED_SELECTOR = YES; 403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 404 | GCC_WARN_UNUSED_FUNCTION = YES; 405 | GCC_WARN_UNUSED_VARIABLE = YES; 406 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 407 | MTL_ENABLE_DEBUG_INFO = NO; 408 | SDKROOT = iphoneos; 409 | SUPPORTED_PLATFORMS = iphoneos; 410 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 411 | TARGETED_DEVICE_FAMILY = "1,2"; 412 | VALIDATE_PRODUCT = YES; 413 | }; 414 | name = Release; 415 | }; 416 | 97C147061CF9000F007C117D /* Debug */ = { 417 | isa = XCBuildConfiguration; 418 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 419 | buildSettings = { 420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 421 | CLANG_ENABLE_MODULES = YES; 422 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 423 | ENABLE_BITCODE = NO; 424 | FRAMEWORK_SEARCH_PATHS = ( 425 | "$(inherited)", 426 | "$(PROJECT_DIR)/Flutter", 427 | ); 428 | INFOPLIST_FILE = Runner/Info.plist; 429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 430 | LIBRARY_SEARCH_PATHS = ( 431 | "$(inherited)", 432 | "$(PROJECT_DIR)/Flutter", 433 | ); 434 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 435 | PRODUCT_NAME = "$(TARGET_NAME)"; 436 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 437 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 438 | SWIFT_VERSION = 5.0; 439 | VERSIONING_SYSTEM = "apple-generic"; 440 | }; 441 | name = Debug; 442 | }; 443 | 97C147071CF9000F007C117D /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | CLANG_ENABLE_MODULES = YES; 449 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 450 | ENABLE_BITCODE = NO; 451 | FRAMEWORK_SEARCH_PATHS = ( 452 | "$(inherited)", 453 | "$(PROJECT_DIR)/Flutter", 454 | ); 455 | INFOPLIST_FILE = Runner/Info.plist; 456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 457 | LIBRARY_SEARCH_PATHS = ( 458 | "$(inherited)", 459 | "$(PROJECT_DIR)/Flutter", 460 | ); 461 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 462 | PRODUCT_NAME = "$(TARGET_NAME)"; 463 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 464 | SWIFT_VERSION = 5.0; 465 | VERSIONING_SYSTEM = "apple-generic"; 466 | }; 467 | name = Release; 468 | }; 469 | /* End XCBuildConfiguration section */ 470 | 471 | /* Begin XCConfigurationList section */ 472 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | 97C147031CF9000F007C117D /* Debug */, 476 | 97C147041CF9000F007C117D /* Release */, 477 | 249021D3217E4FDB00AE95B9 /* Profile */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 483 | isa = XCConfigurationList; 484 | buildConfigurations = ( 485 | 97C147061CF9000F007C117D /* Debug */, 486 | 97C147071CF9000F007C117D /* Release */, 487 | 249021D4217E4FDB00AE95B9 /* Profile */, 488 | ); 489 | defaultConfigurationIsVisible = 0; 490 | defaultConfigurationName = Release; 491 | }; 492 | /* End XCConfigurationList section */ 493 | }; 494 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 495 | } 496 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/color_output.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/services.dart'; 4 | import 'package:hsluv/hsluvcolor.dart'; 5 | 6 | class ColorOutput extends StatefulWidget { 7 | const ColorOutput({Key? key}) : super(key: key); 8 | 9 | @override 10 | State createState() => _ColorOutputState(); 11 | } 12 | 13 | class _ColorOutputState extends State { 14 | late int currentSegment = PageStorage.of(context) 15 | .readState(context, identifier: const ValueKey("Selectable")) ?? 16 | 0; 17 | 18 | final Map children = const { 19 | 0: Text("HEX"), 20 | 1: Text("RGB"), 21 | 2: Text("HSLuv"), 22 | 3: Text("HSV"), 23 | }; 24 | 25 | void copyToClipboard(BuildContext context, String text) { 26 | Clipboard.setData(ClipboardData(text: text)); 27 | 28 | ScaffoldMessenger.of(context).hideCurrentSnackBar(); 29 | final snackBar = SnackBar( 30 | content: Text('$text copied'), 31 | duration: const Duration(milliseconds: 1000), 32 | ); 33 | ScaffoldMessenger.of(context).showSnackBar(snackBar); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | final surface = Theme.of(context).colorScheme.surfaceContainer; 39 | final background = Theme.of(context).colorScheme.surface; 40 | 41 | final lum = HSLuvColor.fromColor(background).lightness; 42 | 43 | final arr = [ 44 | Theme.of(context).colorScheme.primary, 45 | Theme.of(context).colorScheme.secondary, 46 | Theme.of(context).colorScheme.surfaceContainer, 47 | Theme.of(context).colorScheme.surface, 48 | ]; 49 | 50 | return Padding( 51 | padding: const EdgeInsets.all(8), 52 | child: Column( 53 | crossAxisAlignment: CrossAxisAlignment.stretch, 54 | mainAxisAlignment: MainAxisAlignment.center, 55 | children: [ 56 | CupertinoSlidingSegmentedControl( 57 | children: children, 58 | backgroundColor: 59 | Theme.of(context).colorScheme.onSurface.withOpacity(0.20), 60 | thumbColor: surface, 61 | onValueChanged: onValueChanged, 62 | groupValue: currentSegment, 63 | ), 64 | const SizedBox(height: 8), 65 | for (int i = 0; i < arr.length; i++) 66 | Padding( 67 | padding: const EdgeInsets.symmetric(vertical: 4), 68 | child: OutlinedButton( 69 | style: OutlinedButton.styleFrom( 70 | foregroundColor: arr[i], 71 | padding: const EdgeInsets.all(16), 72 | side: BorderSide(color: arr[i], width: 2), 73 | ), 74 | child: Text( 75 | arr[i].retrieveColorStr(currentSegment), 76 | style: TextStyle( 77 | color: lum > 50 ? Colors.black : Colors.white, 78 | ), 79 | ), 80 | onPressed: () { 81 | copyToClipboard( 82 | context, 83 | arr[i].retrieveColorStr(currentSegment), 84 | ); 85 | }, 86 | ), 87 | ), 88 | ], 89 | ), 90 | ); 91 | } 92 | 93 | void onValueChanged(int? newValue) { 94 | if (newValue == null) { 95 | return; 96 | } 97 | 98 | setState(() { 99 | currentSegment = newValue; 100 | PageStorage.of(context).writeState(context, currentSegment, 101 | identifier: const ValueKey("Selectable")); 102 | }); 103 | } 104 | } 105 | 106 | extension on Color { 107 | String retrieveColorStr(int kind) { 108 | switch (kind) { 109 | case 0: 110 | return "#${value.toRadixString(16).substring(2)}"; 111 | case 1: 112 | return "R:$red G:$green B:$blue"; 113 | case 2: 114 | final hsluv = HSLuvColor.fromColor(this); 115 | return "H:${hsluv.hue.round()} S:${hsluv.saturation.round()} L:${hsluv.lightness.round()}"; 116 | case 3: 117 | final hsv = HSVColor.fromColor(this); 118 | return "H:${hsv.hue.round()} S:${(hsv.saturation * 100).round()} V:${(hsv.value * 100).round()}"; 119 | default: 120 | return "error!"; 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:color_blindness/color_blindness.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:random_color_scheme/random_color_scheme.dart'; 4 | import 'package:url_launcher/url_launcher.dart'; 5 | 6 | import 'preview/chat_preview.dart'; 7 | import 'preview/social_preview.dart'; 8 | 9 | void main() { 10 | runApp(const MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | const MyApp({Key? key}) : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return MaterialApp( 19 | title: 'Color Blindness', 20 | home: const RefreshableHome(), 21 | theme: ThemeData( 22 | colorScheme: const ColorScheme.light( 23 | primary: Color(0xffC2410C), 24 | ), 25 | ), 26 | ); 27 | } 28 | } 29 | 30 | class RefreshableHome extends StatelessWidget { 31 | const RefreshableHome({Key? key}) : super(key: key); 32 | 33 | @override 34 | Widget build(BuildContext context) { 35 | return Scaffold( 36 | body: const ThemeScreen(), 37 | appBar: AppBar( 38 | backgroundColor: Colors.white, 39 | title: const Text( 40 | "Color Blindness Color Scheme", 41 | style: TextStyle(color: Colors.black), 42 | ), 43 | actions: [ 44 | IconButton( 45 | icon: const Icon( 46 | Icons.code_rounded, 47 | color: Colors.black, 48 | ), 49 | tooltip: "Source", 50 | onPressed: () async { 51 | await launchUrl(Uri.parse( 52 | "https://github.com/bernaferrari/ColorBlindnessFlutter")); 53 | }, 54 | ) 55 | ], 56 | elevation: 0, 57 | ), 58 | ); 59 | } 60 | } 61 | 62 | class ThemeScreen extends StatefulWidget { 63 | const ThemeScreen({Key? key}) : super(key: key); 64 | 65 | @override 66 | State createState() => _ThemeScreenState(); 67 | } 68 | 69 | class _ThemeScreenState extends State { 70 | double sliderValue = 0; 71 | ColorBlindnessType typeSelected = ColorBlindnessType.none; 72 | int seed = 0; 73 | 74 | Theme customThemeChild({required int i, required bool isDark}) { 75 | return Theme( 76 | data: ThemeData( 77 | colorScheme: colorBlindnessColorScheme( 78 | randomColorScheme(seed: i + seed, isDark: isDark, shouldPrint: false), 79 | typeSelected, 80 | ), 81 | outlinedButtonTheme: OutlinedButtonThemeData( 82 | style: OutlinedButton.styleFrom( 83 | shape: RoundedRectangleBorder( 84 | borderRadius: BorderRadius.circular(8), 85 | ), 86 | ), 87 | ), 88 | cardTheme: CardTheme( 89 | elevation: 0, 90 | shape: RoundedRectangleBorder( 91 | borderRadius: BorderRadius.circular(8), 92 | ), 93 | ), 94 | ), 95 | child: const ThemeItem(), 96 | ); 97 | } 98 | 99 | String typesToStr() { 100 | final str = typeSelected.toString().substring(19); 101 | return str[0].toUpperCase() + str.substring(1); 102 | } 103 | 104 | String affectedToStr() { 105 | const m = "of males"; 106 | const f = "of females"; 107 | const p = "of population"; 108 | 109 | switch (typeSelected) { 110 | case ColorBlindnessType.none: 111 | return "most of the population"; 112 | case ColorBlindnessType.protanomaly: 113 | return "1% $m, 01% $f"; 114 | case ColorBlindnessType.deuteranomaly: 115 | return "6% $m, 0.4% $f"; 116 | case ColorBlindnessType.tritanomaly: 117 | return "01% $p"; 118 | case ColorBlindnessType.protanopia: 119 | return "1% $m"; 120 | case ColorBlindnessType.deuteranopia: 121 | return "1% $m"; 122 | case ColorBlindnessType.tritanopia: 123 | return "less than 1% $p"; 124 | case ColorBlindnessType.achromatopsia: 125 | return "003% $p"; 126 | case ColorBlindnessType.achromatomaly: 127 | return "001% $p"; 128 | default: 129 | // this should never be called. 130 | return ""; 131 | } 132 | } 133 | 134 | @override 135 | Widget build(BuildContext context) { 136 | final condition = MediaQuery.of(context).size.width > 950; 137 | 138 | return Padding( 139 | padding: const EdgeInsets.all(4), 140 | child: SingleChildScrollView( 141 | child: Column( 142 | children: [ 143 | Card( 144 | elevation: 0, 145 | color: const Color(0xffFFF7ED), 146 | shape: RoundedRectangleBorder( 147 | side: const BorderSide(width: 2, color: Color(0xffFED7AA)), 148 | borderRadius: BorderRadius.circular(8), 149 | ), 150 | child: Padding( 151 | padding: const EdgeInsets.all(16), 152 | child: Text( 153 | """ 154 | This is the sample for a library. 155 | The idea is for you to plug colorBlindnessColorScheme() into your apps.""", 156 | style: Theme.of(context).textTheme.titleSmall, 157 | textAlign: TextAlign.center, 158 | ), 159 | ), 160 | ), 161 | const SizedBox(height: 24), 162 | Text( 163 | typesToStr(), 164 | style: Theme.of(context).textTheme.titleLarge?.copyWith( 165 | fontWeight: FontWeight.w600, 166 | ), 167 | textAlign: TextAlign.center, 168 | ), 169 | Text( 170 | affectedToStr(), 171 | style: Theme.of(context).textTheme.titleSmall, 172 | textAlign: TextAlign.center, 173 | ), 174 | const SizedBox(height: 8), 175 | ConstrainedBox( 176 | constraints: const BoxConstraints(maxWidth: 400), 177 | child: Slider( 178 | min: 0, 179 | max: 7, 180 | divisions: 7, 181 | value: sliderValue, 182 | onChanged: (value) { 183 | setState(() { 184 | sliderValue = value; 185 | typeSelected = 186 | ColorBlindnessType.values[sliderValue.toInt()]; 187 | }); 188 | }, 189 | ), 190 | ), 191 | ElevatedButton.icon( 192 | style: ElevatedButton.styleFrom( 193 | padding: 194 | const EdgeInsets.symmetric(horizontal: 24, vertical: 16), 195 | shape: RoundedRectangleBorder( 196 | borderRadius: BorderRadius.circular(8), 197 | ), 198 | ), 199 | label: const Text("Randomize Themes"), 200 | icon: const Icon(Icons.shuffle_rounded, size: 16), 201 | onPressed: () { 202 | setState(() { 203 | seed += 4; 204 | }); 205 | }, 206 | ), 207 | const SizedBox(height: 16), 208 | for (int i = 0; i < 3; i++) 209 | Flex( 210 | direction: condition ? Axis.horizontal : Axis.vertical, 211 | children: [ 212 | Flexible( 213 | flex: condition ? 1 : 0, 214 | child: customThemeChild(i: i, isDark: true), 215 | ), 216 | Flexible( 217 | flex: condition ? 1 : 0, 218 | child: customThemeChild(i: i, isDark: false), 219 | ), 220 | ], 221 | ), 222 | ], 223 | ), 224 | ), 225 | ); 226 | } 227 | } 228 | 229 | class ThemeItem extends StatelessWidget { 230 | const ThemeItem({Key? key}) : super(key: key); 231 | 232 | @override 233 | Widget build(BuildContext context) { 234 | return Card( 235 | color: Theme.of(context).colorScheme.surface, 236 | elevation: 0, 237 | child: const Row( 238 | children: [ 239 | Expanded(child: SocialPreview()), 240 | Expanded(child: ChatPreview()), 241 | ], 242 | ), 243 | ); 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /example/lib/preview/chat_preview.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ChatPreview extends StatelessWidget { 4 | const ChatPreview({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | final primary = Theme.of(context).colorScheme.primary; 9 | 10 | return Column( 11 | children: [ 12 | const SizedBox(height: 8), 13 | Text( 14 | "Chat", 15 | style: TextStyle( 16 | color: primary, fontSize: 22, fontWeight: FontWeight.w800), 17 | ), 18 | Text( 19 | "14 participants", 20 | style: TextStyle( 21 | color: primary, fontSize: 14, fontWeight: FontWeight.w700), 22 | ), 23 | // ListTile( 24 | // title: Text("Bernardo"), 25 | // subtitle: Text("What's new?"), 26 | // leading: Padding( 27 | // padding: const EdgeInsets.all(8), 28 | // child: Icon( 29 | // Icons.accessibility_new_rounded, 30 | // size: 24, 31 | // color: primary, 32 | // ), 33 | // ), 34 | // trailing: Icon( 35 | // Icons.done, 36 | // size: 16, 37 | // color: primary, 38 | // ), 39 | // ), 40 | ListTile( 41 | title: const Text( 42 | "Alfred", 43 | overflow: TextOverflow.ellipsis, 44 | ), 45 | subtitle: const Text( 46 | "Here is the weather for today", 47 | overflow: TextOverflow.ellipsis, 48 | ), 49 | leading: Padding( 50 | padding: const EdgeInsets.all(8), 51 | child: Icon(Icons.wb_sunny_outlined, size: 24, color: primary), 52 | ), 53 | trailing: Icon(Icons.done, size: 16, color: primary), 54 | ), 55 | Row( 56 | mainAxisAlignment: MainAxisAlignment.center, 57 | children: [ 58 | Icon(Icons.graphic_eq, color: primary), 59 | const SizedBox(width: 8), 60 | Icon( 61 | Icons.graphic_eq, 62 | color: Theme.of(context).colorScheme.secondary, 63 | ), 64 | ], 65 | ), 66 | ], 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /example/lib/preview/social_preview.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../color_output.dart'; 4 | 5 | class SocialPreview extends StatelessWidget { 6 | const SocialPreview({Key? key}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Card( 11 | margin: const EdgeInsets.all(8), 12 | clipBehavior: Clip.antiAlias, 13 | color: Theme.of(context).colorScheme.surface, 14 | child: Column( 15 | crossAxisAlignment: CrossAxisAlignment.stretch, 16 | children: [ 17 | Padding( 18 | padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), 19 | child: Text( 20 | "What's happening", 21 | overflow: TextOverflow.ellipsis, 22 | style: Theme.of(context) 23 | .textTheme 24 | .titleLarge 25 | ?.copyWith(fontWeight: FontWeight.w900), 26 | ), 27 | ), 28 | Container( 29 | color: Theme.of(context).colorScheme.onSurface.withOpacity(0.24), 30 | height: 1, 31 | ), 32 | ListTile( 33 | title: const Text("Trending", overflow: TextOverflow.ellipsis), 34 | subtitle: 35 | const Text("Design updates", overflow: TextOverflow.ellipsis), 36 | contentPadding: const EdgeInsets.symmetric(horizontal: 8), 37 | leading: Padding( 38 | padding: const EdgeInsets.all(8), 39 | child: Icon( 40 | Icons.account_balance, 41 | size: 24, 42 | color: Theme.of(context).colorScheme.primary, 43 | ), 44 | ), 45 | trailing: Padding( 46 | padding: const EdgeInsets.only(right: 8), 47 | child: ElevatedButton.icon( 48 | style: ElevatedButton.styleFrom( 49 | padding: const EdgeInsets.all(16), 50 | elevation: 0, 51 | shape: RoundedRectangleBorder( 52 | borderRadius: BorderRadius.circular(8), 53 | ), 54 | ), 55 | icon: const Icon(Icons.share), 56 | label: Text( 57 | "Export", 58 | style: Theme.of(context).textTheme.bodyLarge?.copyWith( 59 | color: Theme.of(context).colorScheme.onPrimary, 60 | ), 61 | ), 62 | onPressed: () { 63 | showDialog( 64 | context: context, 65 | builder: (BuildContext context) { 66 | return SimpleDialog( 67 | title: const Text('Export (click to copy)'), 68 | titlePadding: const EdgeInsets.only(left: 16, top: 16), 69 | backgroundColor: 70 | Theme.of(context).brightness == Brightness.dark 71 | ? const Color(0xff080808) 72 | : Colors.white, 73 | contentPadding: const EdgeInsets.all(8), 74 | children: const [ 75 | ColorOutput(), 76 | ], 77 | ); 78 | }, 79 | ); 80 | }, 81 | ), 82 | ), 83 | ), 84 | Container( 85 | color: Theme.of(context).colorScheme.onSurface.withOpacity(0.24), 86 | height: 1, 87 | ), 88 | Padding( 89 | padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8), 90 | child: Row( 91 | mainAxisAlignment: MainAxisAlignment.center, 92 | children: [ 93 | _NotButton("Primary", Theme.of(context).colorScheme.primary), 94 | const SizedBox(width: 8), 95 | _NotButton( 96 | "Secondary", 97 | Theme.of(context).colorScheme.secondary, 98 | ), 99 | ], 100 | ), 101 | ), 102 | ], 103 | ), 104 | ); 105 | } 106 | } 107 | 108 | class _NotButton extends StatelessWidget { 109 | final String text; 110 | final Color color; 111 | 112 | const _NotButton(this.text, this.color, {Key? key}) : super(key: key); 113 | 114 | @override 115 | Widget build(BuildContext context) { 116 | return Material( 117 | elevation: 0, 118 | color: Colors.transparent, 119 | shape: RoundedRectangleBorder( 120 | side: BorderSide(color: color), 121 | borderRadius: BorderRadius.circular(8), 122 | ), 123 | child: Padding( 124 | padding: const EdgeInsets.all(8), 125 | child: Row( 126 | children: [ 127 | Icon( 128 | Icons.border_inner, 129 | color: color, 130 | size: 16, 131 | ), 132 | const SizedBox(width: 8), 133 | Text( 134 | MediaQuery.of(context).size.width < 400 ? text[0] : text, 135 | style: Theme.of(context) 136 | .textTheme 137 | .bodyMedium! 138 | .copyWith(color: color), 139 | overflow: TextOverflow.ellipsis, 140 | ), 141 | ], 142 | ), 143 | ), 144 | ); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.18.0" 44 | color_blindness: 45 | dependency: "direct main" 46 | description: 47 | path: ".." 48 | relative: true 49 | source: path 50 | version: "0.2.0" 51 | fake_async: 52 | dependency: transitive 53 | description: 54 | name: fake_async 55 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 56 | url: "https://pub.dev" 57 | source: hosted 58 | version: "1.3.1" 59 | flutter: 60 | dependency: "direct main" 61 | description: flutter 62 | source: sdk 63 | version: "0.0.0" 64 | flutter_lints: 65 | dependency: "direct dev" 66 | description: 67 | name: flutter_lints 68 | sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" 69 | url: "https://pub.dev" 70 | source: hosted 71 | version: "4.0.0" 72 | flutter_test: 73 | dependency: "direct dev" 74 | description: flutter 75 | source: sdk 76 | version: "0.0.0" 77 | flutter_web_plugins: 78 | dependency: transitive 79 | description: flutter 80 | source: sdk 81 | version: "0.0.0" 82 | hsluv: 83 | dependency: "direct main" 84 | description: 85 | name: hsluv 86 | sha256: f33e63b0c24ceee0f6492874424aa8edc671ef9a20cc889e4b969284d8f02eb1 87 | url: "https://pub.dev" 88 | source: hosted 89 | version: "1.1.3" 90 | leak_tracker: 91 | dependency: transitive 92 | description: 93 | name: leak_tracker 94 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" 95 | url: "https://pub.dev" 96 | source: hosted 97 | version: "10.0.5" 98 | leak_tracker_flutter_testing: 99 | dependency: transitive 100 | description: 101 | name: leak_tracker_flutter_testing 102 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" 103 | url: "https://pub.dev" 104 | source: hosted 105 | version: "3.0.5" 106 | leak_tracker_testing: 107 | dependency: transitive 108 | description: 109 | name: leak_tracker_testing 110 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 111 | url: "https://pub.dev" 112 | source: hosted 113 | version: "3.0.1" 114 | lints: 115 | dependency: transitive 116 | description: 117 | name: lints 118 | sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" 119 | url: "https://pub.dev" 120 | source: hosted 121 | version: "4.0.0" 122 | matcher: 123 | dependency: transitive 124 | description: 125 | name: matcher 126 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 127 | url: "https://pub.dev" 128 | source: hosted 129 | version: "0.12.16+1" 130 | material_color_utilities: 131 | dependency: transitive 132 | description: 133 | name: material_color_utilities 134 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 135 | url: "https://pub.dev" 136 | source: hosted 137 | version: "0.11.1" 138 | meta: 139 | dependency: transitive 140 | description: 141 | name: meta 142 | sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b" 143 | url: "https://pub.dev" 144 | source: hosted 145 | version: "1.14.0" 146 | path: 147 | dependency: transitive 148 | description: 149 | name: path 150 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 151 | url: "https://pub.dev" 152 | source: hosted 153 | version: "1.9.0" 154 | plugin_platform_interface: 155 | dependency: transitive 156 | description: 157 | name: plugin_platform_interface 158 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 159 | url: "https://pub.dev" 160 | source: hosted 161 | version: "2.1.8" 162 | random_color_scheme: 163 | dependency: "direct main" 164 | description: 165 | name: random_color_scheme 166 | sha256: f9140b04ba7017a8aff66c5603341ace21e6e6dfb6212285bfae5ba4794cdbbe 167 | url: "https://pub.dev" 168 | source: hosted 169 | version: "0.1.4" 170 | sky_engine: 171 | dependency: transitive 172 | description: flutter 173 | source: sdk 174 | version: "0.0.99" 175 | source_span: 176 | dependency: transitive 177 | description: 178 | name: source_span 179 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 180 | url: "https://pub.dev" 181 | source: hosted 182 | version: "1.10.0" 183 | stack_trace: 184 | dependency: transitive 185 | description: 186 | name: stack_trace 187 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 188 | url: "https://pub.dev" 189 | source: hosted 190 | version: "1.11.1" 191 | stream_channel: 192 | dependency: transitive 193 | description: 194 | name: stream_channel 195 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 196 | url: "https://pub.dev" 197 | source: hosted 198 | version: "2.1.2" 199 | string_scanner: 200 | dependency: transitive 201 | description: 202 | name: string_scanner 203 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 204 | url: "https://pub.dev" 205 | source: hosted 206 | version: "1.2.0" 207 | term_glyph: 208 | dependency: transitive 209 | description: 210 | name: term_glyph 211 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 212 | url: "https://pub.dev" 213 | source: hosted 214 | version: "1.2.1" 215 | test_api: 216 | dependency: transitive 217 | description: 218 | name: test_api 219 | sha256: "2419f20b0c8677b2d67c8ac4d1ac7372d862dc6c460cdbb052b40155408cd794" 220 | url: "https://pub.dev" 221 | source: hosted 222 | version: "0.7.1" 223 | url_launcher: 224 | dependency: "direct main" 225 | description: 226 | name: url_launcher 227 | sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" 228 | url: "https://pub.dev" 229 | source: hosted 230 | version: "6.3.0" 231 | url_launcher_android: 232 | dependency: transitive 233 | description: 234 | name: url_launcher_android 235 | sha256: "17cd5e205ea615e2c6ea7a77323a11712dffa0720a8a90540db57a01347f9ad9" 236 | url: "https://pub.dev" 237 | source: hosted 238 | version: "6.3.2" 239 | url_launcher_ios: 240 | dependency: transitive 241 | description: 242 | name: url_launcher_ios 243 | sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89" 244 | url: "https://pub.dev" 245 | source: hosted 246 | version: "6.3.0" 247 | url_launcher_linux: 248 | dependency: transitive 249 | description: 250 | name: url_launcher_linux 251 | sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 252 | url: "https://pub.dev" 253 | source: hosted 254 | version: "3.1.1" 255 | url_launcher_macos: 256 | dependency: transitive 257 | description: 258 | name: url_launcher_macos 259 | sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" 260 | url: "https://pub.dev" 261 | source: hosted 262 | version: "3.2.0" 263 | url_launcher_platform_interface: 264 | dependency: transitive 265 | description: 266 | name: url_launcher_platform_interface 267 | sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" 268 | url: "https://pub.dev" 269 | source: hosted 270 | version: "2.3.2" 271 | url_launcher_web: 272 | dependency: transitive 273 | description: 274 | name: url_launcher_web 275 | sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a" 276 | url: "https://pub.dev" 277 | source: hosted 278 | version: "2.3.1" 279 | url_launcher_windows: 280 | dependency: transitive 281 | description: 282 | name: url_launcher_windows 283 | sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 284 | url: "https://pub.dev" 285 | source: hosted 286 | version: "3.1.1" 287 | vector_math: 288 | dependency: transitive 289 | description: 290 | name: vector_math 291 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 292 | url: "https://pub.dev" 293 | source: hosted 294 | version: "2.1.4" 295 | vm_service: 296 | dependency: transitive 297 | description: 298 | name: vm_service 299 | sha256: "7475cb4dd713d57b6f7464c0e13f06da0d535d8b2067e188962a59bac2cf280b" 300 | url: "https://pub.dev" 301 | source: hosted 302 | version: "14.2.2" 303 | web: 304 | dependency: transitive 305 | description: 306 | name: web 307 | sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" 308 | url: "https://pub.dev" 309 | source: hosted 310 | version: "0.5.1" 311 | sdks: 312 | dart: ">=3.3.0 <4.0.0" 313 | flutter: ">=3.19.0" 314 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: Example for Color Blindness on Flutter. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' 7 | version: 1.0.1 8 | 9 | environment: 10 | sdk: '>=3.0.0 <4.0.0' 11 | 12 | dependencies: 13 | flutter: 14 | sdk: flutter 15 | url_launcher: ^6.3.0 16 | hsluv: ^1.1.3 17 | random_color_scheme: ^0.1.4 18 | color_blindness: 19 | path: ../ 20 | 21 | dev_dependencies: 22 | flutter_lints: ^4.0.0 23 | flutter_test: 24 | sdk: flutter 25 | 26 | flutter: 27 | uses-material-design: true -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:example/main.dart'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_test/flutter_test.dart'; 11 | 12 | void main() { 13 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 14 | // Build our app and trigger a frame. 15 | await tester.pumpWidget(const MyApp()); 16 | 17 | // Verify that our counter starts at 0. 18 | expect(find.text('0'), findsOneWidget); 19 | expect(find.text('1'), findsNothing); 20 | 21 | // Tap the '+' icon and trigger a frame. 22 | await tester.tap(find.byIcon(Icons.add)); 23 | await tester.pump(); 24 | 25 | // Verify that our counter has incremented. 26 | expect(find.text('0'), findsNothing); 27 | expect(find.text('1'), findsOneWidget); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bernaferrari/ColorBlindnessFlutter/36c723feec458aa15be2ce53956d051fa2f55422/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Color Blindness on Flutter 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Color Blindness Color Scheme Experiments", 3 | "short_name": "CBCS Experiments", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /lib/color_blindness.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | export 'package:color_blindness/color_blindness_color_scheme.dart'; 4 | 5 | /// The color blindness types. 6 | /// Type [none] is included as a convenience. 7 | enum ColorBlindnessType { 8 | none, 9 | protanomaly, 10 | deuteranomaly, 11 | tritanomaly, 12 | protanopia, 13 | deuteranopia, 14 | tritanopia, 15 | achromatopsia, 16 | achromatomaly, 17 | } 18 | 19 | /// Simulates color blindness in a single color. 20 | /// Input: a [Color] and a [ColorBlindnessType] 21 | /// Output: the simulated [Color] 22 | Color colorBlindness(Color color, ColorBlindnessType type) { 23 | switch (type) { 24 | case ColorBlindnessType.none: 25 | return color; 26 | case ColorBlindnessType.protanomaly: 27 | return protanomaly(color); 28 | case ColorBlindnessType.deuteranomaly: 29 | return deuteranomaly(color); 30 | case ColorBlindnessType.tritanomaly: 31 | return tritanomaly(color); 32 | case ColorBlindnessType.protanopia: 33 | return protanopia(color); 34 | case ColorBlindnessType.deuteranopia: 35 | return deuteranopia(color); 36 | case ColorBlindnessType.tritanopia: 37 | return tritanopia(color); 38 | case ColorBlindnessType.achromatopsia: 39 | return achromatopsia(color); 40 | case ColorBlindnessType.achromatomaly: 41 | return achromatomaly(color); 42 | default: 43 | // this should never be called. 44 | return const Color(0x00000000); 45 | } 46 | } 47 | 48 | /// Converted to Dart from: https://github.com/jordidekock/Colorblinds 49 | 50 | /// Malfunctioning green. 51 | Color deuteranomaly(Color color) { 52 | final double r = (color.red * 0.80) + (color.green * 0.20) + (color.blue * 0); 53 | final double g = 54 | (color.red * 0.25833) + (color.green * 0.74167) + (color.blue * 0); 55 | final double b = 56 | (color.red * 0.0) + (color.green * 0.14167) + (color.blue * 0.85833); 57 | 58 | return Color.fromARGB(255, r.round(), g.round(), b.round()); 59 | } 60 | 61 | /// Missing red. 62 | Color protanopia(Color color) { 63 | final double r = 64 | (color.red * 0.56667) + (color.green * 0.43333) + (color.blue * 0); 65 | final double g = 66 | (color.red * 0.55833) + (color.green * 0.44167) + (color.blue * 0); 67 | final double b = 68 | (color.red * 0.0) + (color.green * 0.24167) + (color.blue * 0.75833); 69 | 70 | return Color.fromARGB(255, r.round(), g.round(), b.round()); 71 | } 72 | 73 | /// Missing green. 74 | Color deuteranopia(Color color) { 75 | final double r = 76 | (color.red * 0.625) + (color.green * 0.375) + (color.blue * 0); 77 | final double g = (color.red * 0.7) + (color.green * 0.3) + (color.blue * 0); 78 | final double b = (color.red * 0.0) + (color.green * 0.3) + (color.blue * 0.7); 79 | 80 | return Color.fromARGB(255, r.round(), g.round(), b.round()); 81 | } 82 | 83 | /// Malfunctioning red. 84 | Color protanomaly(Color color) { 85 | final double r = 86 | (color.red * 0.81667) + (color.green * 0.18333) + (color.blue * 0); 87 | final double g = 88 | (color.red * 0.33333) + (color.green * 0.66667) + (color.blue * 0); 89 | final double b = 90 | (color.red * 0.0) + (color.green * 0.125) + (color.blue * 0.875); 91 | 92 | return Color.fromARGB(255, r.round(), g.round(), b.round()); 93 | } 94 | 95 | /// Missing blue. 96 | Color tritanopia(Color color) { 97 | final double r = (color.red * 0.95) + (color.green * 0.05) + (color.blue * 0); 98 | final double g = 99 | (color.red * 0.0) + (color.green * 0.43) + (color.blue * 0.56); 100 | final double b = 101 | (color.red * 0.0) + (color.green * 0.4755) + (color.blue * 0.525); 102 | 103 | return Color.fromARGB(255, r.round(), g.round(), b.round()); 104 | } 105 | 106 | /// Malfunctioning blue. 107 | Color tritanomaly(Color color) { 108 | final double r = 109 | (color.red * 0.9667) + (color.green * 0.033) + (color.blue * 0); 110 | final double g = 111 | (color.red * 0.0) + (color.green * 0.733) + (color.blue * 0.2667); 112 | final double b = 113 | (color.red * 0.0) + (color.green * 0.183) + (color.blue * 0.8167); 114 | 115 | return Color.fromARGB(255, r.round(), g.round(), b.round()); 116 | } 117 | 118 | /// Less severe form of total color blind (monochromatic). 119 | Color achromatomaly(Color color) { 120 | final double r = 121 | (color.red * 0.618) + (color.green * 0.32) + (color.blue * 0.062); 122 | final double g = 123 | (color.red * 0.163) + (color.green * 0.775) + (color.blue * 0.062); 124 | final double b = 125 | (color.red * 0.163) + (color.green * 0.32) + (color.blue * 0.516); 126 | 127 | return Color.fromARGB(255, r.round(), g.round(), b.round()); 128 | } 129 | 130 | /// Totally color blind (monochromatic). 131 | Color achromatopsia(Color color) { 132 | final double r = 133 | (color.red * 0.299) + (color.green * 0.587) + (color.blue * 0.114); 134 | final double g = 135 | (color.red * 0.299) + (color.green * 0.587) + (color.blue * 0.114); 136 | final double b = 137 | (color.red * 0.299) + (color.green * 0.587) + (color.blue * 0.114); 138 | 139 | return Color.fromARGB(255, r.round(), g.round(), b.round()); 140 | } 141 | -------------------------------------------------------------------------------- /lib/color_blindness_color_scheme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'color_blindness.dart'; 4 | 5 | /// Simulates color blindness for every color in a ColorScheme. 6 | /// 7 | /// Input: 8 | /// ColorScheme: the ColorScheme you are using as your theme. 9 | /// ColorBlindnessType: the type to be used. 10 | /// 11 | /// Output: 12 | /// a ColorScheme containing all colors modified. 13 | ColorScheme colorBlindnessColorScheme( 14 | ColorScheme scheme, 15 | ColorBlindnessType type, 16 | ) { 17 | return ColorScheme( 18 | brightness: scheme.brightness, 19 | primary: colorBlindness(scheme.primary, type), 20 | onPrimary: colorBlindness(scheme.onPrimary, type), 21 | primaryContainer: colorBlindness(scheme.primaryContainer, type), 22 | onPrimaryContainer: colorBlindness(scheme.onPrimaryContainer, type), 23 | primaryFixed: colorBlindness(scheme.primaryFixed, type), 24 | primaryFixedDim: colorBlindness(scheme.primaryFixedDim, type), 25 | onPrimaryFixed: colorBlindness(scheme.onPrimaryFixed, type), 26 | onPrimaryFixedVariant: colorBlindness(scheme.onPrimaryFixedVariant, type), 27 | secondary: colorBlindness(scheme.secondary, type), 28 | onSecondary: colorBlindness(scheme.onSecondary, type), 29 | secondaryContainer: colorBlindness(scheme.secondaryContainer, type), 30 | onSecondaryContainer: colorBlindness(scheme.onSecondaryContainer, type), 31 | secondaryFixed: colorBlindness(scheme.secondaryFixed, type), 32 | secondaryFixedDim: colorBlindness(scheme.secondaryFixedDim, type), 33 | onSecondaryFixed: colorBlindness(scheme.onSecondaryFixed, type), 34 | onSecondaryFixedVariant: 35 | colorBlindness(scheme.onSecondaryFixedVariant, type), 36 | tertiary: colorBlindness(scheme.tertiary, type), 37 | onTertiary: colorBlindness(scheme.onTertiary, type), 38 | tertiaryContainer: colorBlindness(scheme.tertiaryContainer, type), 39 | onTertiaryContainer: colorBlindness(scheme.onTertiaryContainer, type), 40 | tertiaryFixed: colorBlindness(scheme.tertiaryFixed, type), 41 | tertiaryFixedDim: colorBlindness(scheme.tertiaryFixedDim, type), 42 | onTertiaryFixed: colorBlindness(scheme.onTertiaryFixed, type), 43 | onTertiaryFixedVariant: colorBlindness(scheme.onTertiaryFixedVariant, type), 44 | error: colorBlindness(scheme.error, type), 45 | onError: colorBlindness(scheme.onError, type), 46 | errorContainer: colorBlindness(scheme.errorContainer, type), 47 | onErrorContainer: colorBlindness(scheme.onErrorContainer, type), 48 | surface: colorBlindness(scheme.surface, type), 49 | onSurface: colorBlindness(scheme.onSurface, type), 50 | surfaceDim: colorBlindness(scheme.surfaceDim, type), 51 | surfaceBright: colorBlindness(scheme.surfaceBright, type), 52 | surfaceContainerLowest: colorBlindness(scheme.surfaceContainerLowest, type), 53 | surfaceContainerLow: colorBlindness(scheme.surfaceContainerLow, type), 54 | surfaceContainer: colorBlindness(scheme.surfaceContainer, type), 55 | surfaceContainerHigh: colorBlindness(scheme.surfaceContainerHigh, type), 56 | surfaceContainerHighest: 57 | colorBlindness(scheme.surfaceContainerHighest, type), 58 | onSurfaceVariant: colorBlindness(scheme.onSurfaceVariant, type), 59 | outline: colorBlindness(scheme.outline, type), 60 | outlineVariant: colorBlindness(scheme.outlineVariant, type), 61 | shadow: colorBlindness(scheme.shadow, type), 62 | scrim: colorBlindness(scheme.scrim, type), 63 | inverseSurface: colorBlindness(scheme.inverseSurface, type), 64 | onInverseSurface: colorBlindness(scheme.onInverseSurface, type), 65 | inversePrimary: colorBlindness(scheme.inversePrimary, type), 66 | surfaceTint: colorBlindness(scheme.surfaceTint, type), 67 | ); 68 | } 69 | -------------------------------------------------------------------------------- /lib/color_blindness_contrast_checker.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'color_blindness.dart'; 6 | 7 | /// This method simulates color blindness in a ColorScheme and compares 8 | /// [primary, secondary] against [background, surface]. 9 | /// 10 | /// Should be used in CI and tests. 11 | /// 12 | /// Input: 13 | /// ColorScheme: the ColorScheme you are using as your theme. 14 | /// double: the minimum threshold in WCAG 2.1 where it should pass. 15 | /// The value is usually 4.5 (AA) or 7.0 (AAA). Contrast ranges from 0 to 21. 16 | /// 17 | /// Output: 18 | /// if successful: nothing 19 | /// if there is an error: it will throw an exception 20 | void colorBlindnessAssertContrast(ColorScheme scheme, 21 | [double minThreshold = 4.5]) { 22 | for (ColorBlindnessType type in ColorBlindnessType.values) { 23 | final updatedScheme = colorBlindnessColorScheme(scheme, type); 24 | 25 | void calculate({ 26 | required Color aColor, 27 | required Color bColor, 28 | required String aStr, 29 | required String bStr, 30 | }) { 31 | final contrast = _calculateContrast(aColor, bColor); 32 | if (contrast < minThreshold) { 33 | throw Exception( 34 | "Fail! For ${type.toString().substring(19)}, $aStr ($aColor) on $bStr ($bColor) got value ${contrast.toStringAsFixed(2)}"); 35 | } 36 | } 37 | 38 | calculate( 39 | aColor: updatedScheme.primary, 40 | bColor: updatedScheme.surface, 41 | aStr: "primary", 42 | bStr: "background", 43 | ); 44 | 45 | calculate( 46 | aColor: updatedScheme.primary, 47 | bColor: updatedScheme.surface, 48 | aStr: "primary", 49 | bStr: "surface", 50 | ); 51 | 52 | calculate( 53 | aColor: updatedScheme.secondary, 54 | bColor: updatedScheme.surface, 55 | aStr: "secondary", 56 | bStr: "background", 57 | ); 58 | 59 | calculate( 60 | aColor: updatedScheme.secondary, 61 | bColor: updatedScheme.surface, 62 | aStr: "secondary", 63 | bStr: "surface", 64 | ); 65 | } 66 | } 67 | 68 | double _calculateContrast(Color color1, Color color2) { 69 | final double colorFirstLum = color1.computeLuminance(); 70 | final double colorSecondLum = color2.computeLuminance(); 71 | 72 | final double l1 = min(colorFirstLum, colorSecondLum); 73 | final double l2 = max(colorFirstLum, colorSecondLum); 74 | 75 | return 1 / ((l1 + 0.05) / (l2 + 0.05)); 76 | } 77 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.18.0" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_test: 58 | dependency: "direct dev" 59 | description: flutter 60 | source: sdk 61 | version: "0.0.0" 62 | leak_tracker: 63 | dependency: transitive 64 | description: 65 | name: leak_tracker 66 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" 67 | url: "https://pub.dev" 68 | source: hosted 69 | version: "10.0.5" 70 | leak_tracker_flutter_testing: 71 | dependency: transitive 72 | description: 73 | name: leak_tracker_flutter_testing 74 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" 75 | url: "https://pub.dev" 76 | source: hosted 77 | version: "3.0.5" 78 | leak_tracker_testing: 79 | dependency: transitive 80 | description: 81 | name: leak_tracker_testing 82 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 83 | url: "https://pub.dev" 84 | source: hosted 85 | version: "3.0.1" 86 | matcher: 87 | dependency: transitive 88 | description: 89 | name: matcher 90 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 91 | url: "https://pub.dev" 92 | source: hosted 93 | version: "0.12.16+1" 94 | material_color_utilities: 95 | dependency: transitive 96 | description: 97 | name: material_color_utilities 98 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 99 | url: "https://pub.dev" 100 | source: hosted 101 | version: "0.11.1" 102 | meta: 103 | dependency: transitive 104 | description: 105 | name: meta 106 | sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b" 107 | url: "https://pub.dev" 108 | source: hosted 109 | version: "1.14.0" 110 | path: 111 | dependency: transitive 112 | description: 113 | name: path 114 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 115 | url: "https://pub.dev" 116 | source: hosted 117 | version: "1.9.0" 118 | sky_engine: 119 | dependency: transitive 120 | description: flutter 121 | source: sdk 122 | version: "0.0.99" 123 | source_span: 124 | dependency: transitive 125 | description: 126 | name: source_span 127 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 128 | url: "https://pub.dev" 129 | source: hosted 130 | version: "1.10.0" 131 | stack_trace: 132 | dependency: transitive 133 | description: 134 | name: stack_trace 135 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 136 | url: "https://pub.dev" 137 | source: hosted 138 | version: "1.11.1" 139 | stream_channel: 140 | dependency: transitive 141 | description: 142 | name: stream_channel 143 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 144 | url: "https://pub.dev" 145 | source: hosted 146 | version: "2.1.2" 147 | string_scanner: 148 | dependency: transitive 149 | description: 150 | name: string_scanner 151 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 152 | url: "https://pub.dev" 153 | source: hosted 154 | version: "1.2.0" 155 | term_glyph: 156 | dependency: transitive 157 | description: 158 | name: term_glyph 159 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 160 | url: "https://pub.dev" 161 | source: hosted 162 | version: "1.2.1" 163 | test_api: 164 | dependency: transitive 165 | description: 166 | name: test_api 167 | sha256: "2419f20b0c8677b2d67c8ac4d1ac7372d862dc6c460cdbb052b40155408cd794" 168 | url: "https://pub.dev" 169 | source: hosted 170 | version: "0.7.1" 171 | vector_math: 172 | dependency: transitive 173 | description: 174 | name: vector_math 175 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 176 | url: "https://pub.dev" 177 | source: hosted 178 | version: "2.1.4" 179 | vm_service: 180 | dependency: transitive 181 | description: 182 | name: vm_service 183 | sha256: "7475cb4dd713d57b6f7464c0e13f06da0d535d8b2067e188962a59bac2cf280b" 184 | url: "https://pub.dev" 185 | source: hosted 186 | version: "14.2.2" 187 | sdks: 188 | dart: ">=3.3.0 <4.0.0" 189 | flutter: ">=3.18.0-18.0.pre.54" 190 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: color_blindness 2 | description: Color Blindness on Flutter. Works with either color scheme or individual colors. 3 | version: 0.2.0 4 | homepage: https://github.com/bernaferrari/ColorBlindnessFlutter 5 | 6 | environment: 7 | sdk: '>=3.0.0 <4.0.0' 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | dev_dependencies: 14 | flutter_test: 15 | sdk: flutter 16 | -------------------------------------------------------------------------------- /test/color_blindness_color_scheme_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:color_blindness/color_blindness_contrast_checker.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | void main() { 6 | test('test contrast CI', () { 7 | var colorScheme = ColorScheme.dark(); 8 | expect(() => colorBlindnessAssertContrast(colorScheme), throwsException); 9 | 10 | colorScheme = ColorScheme.light(); 11 | expect(() => colorBlindnessAssertContrast(colorScheme), throwsException); 12 | 13 | colorScheme = ColorScheme.light( 14 | primary: const Color(0xff9f0042), 15 | secondary: const Color(0xff1e6100), 16 | ); 17 | expect(() => colorBlindnessAssertContrast(colorScheme), returnsNormally); 18 | 19 | colorScheme = ColorScheme.light( 20 | primary: const Color(0xff00263b), 21 | secondary: const Color(0xff390062), 22 | ); 23 | expect( 24 | () => colorBlindnessAssertContrast(colorScheme, 7.5), returnsNormally); 25 | }); 26 | } 27 | --------------------------------------------------------------------------------