├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example
├── .gitignore
├── .metadata
├── README.md
├── analysis_options.yaml
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── example
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable-v21
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── values-night
│ │ │ │ └── styles.xml
│ │ │ │ └── values
│ │ │ │ └── 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
│ ├── 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
│ └── main.dart
├── pubspec.lock
└── pubspec.yaml
├── images
├── animate-many.gif
├── animate-single.gif
├── board-arrows.png
├── board-orientation.png
├── board.png
├── drag-drop.png
└── hints.gif
├── lib
├── components
│ ├── animated_piece_wrap.dart
│ ├── arrows.dart
│ ├── drop_targets.dart
│ ├── hints.dart
│ ├── hints
│ │ └── move_hint.dart
│ ├── pieces.dart
│ └── squares.dart
├── models
│ ├── arrow.dart
│ ├── arrow_list.dart
│ ├── board_orientation.dart
│ ├── chess_state.dart
│ ├── drop_indicator_args.dart
│ ├── hint_map.dart
│ ├── piece_drop_event.dart
│ ├── piece_map.dart
│ ├── square.dart
│ └── square_info.dart
└── wp_chessboard.dart
├── pubspec.yaml
├── react_example
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
│ └── index.html
└── src
│ ├── App.js
│ ├── index.css
│ ├── index.js
│ └── wp_chessboard
│ └── wp_chessboard.jsx
└── web_example
├── .gitignore
├── .metadata
├── README.md
├── analysis_options.yaml
├── build.sh
├── lib
├── main.dart
└── src
│ ├── js_interop.dart
│ └── js_interop
│ ├── dom.dart
│ ├── helper.dart
│ └── state_manager.dart
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
└── web
├── favicon.png
└── index.html
/.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 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
25 | /pubspec.lock
26 | **/doc/api/
27 | .dart_tool/
28 | .packages
29 | build/
30 |
--------------------------------------------------------------------------------
/.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: 7e9793dee1b85a243edd0e06cb1658e98b077561
8 | channel: stable
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.0.4
2 |
3 | * Prevent an exception when "reusing" the controller (fixed by @topse)
4 |
5 | ## 0.0.3
6 |
7 | * Fix static analysis
8 |
9 | * Update Example to allow casteling
10 |
11 | ## 0.0.2
12 |
13 | * Export all important models directly
14 |
15 | ## 0.0.1
16 |
17 | * Initial Release
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2022 Khadim Fall
3 |
4 | Permission is hereby granted, free of charge, to any person
5 | obtaining a copy of this software and associated documentation
6 | files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge,
8 | publish, distribute, sublicense, and/or sell copies of the Software,
9 | and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included
13 | in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 | USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WP_CHESSBOARD
2 |
3 | 
4 |
5 | A very customizable Chessboard with awesomeness already onboard:
6 |
7 | 👇️ Dragable Pieces
8 |
9 | 🎬️ Move Animations
10 |
11 | 🔄 Orientation
12 |
13 | 💡 Hints
14 |
15 | 💡 Arrows
16 |
17 | ## Features
18 |
19 | ### 👇️ Dragable Pieces
20 |
21 | 
22 |
23 | ### 🎬️ Piece Animations for Single Moves
24 |
25 | 
26 |
27 | ### 🎬️ Piece Animations for position changes/reset
28 |
29 | 
30 |
31 | ### 🔄 Change Orientation
32 |
33 | 
34 |
35 | ### 💡 Display Hints
36 |
37 | 
38 |
39 | ### 💡 Display Arrows
40 |
41 | 
42 |
43 |
44 | ## Usage
45 |
46 | First import the `WPChessboard` widget.
47 | ```dart
48 | import 'package:wp_chessboard/wp_chessboard.dart';
49 | ```
50 |
51 | Then, you are ready to use it
52 |
53 | > You can use your own piece set, in the example we will
54 | > use the `chess_vectors_flutter` package.
55 |
56 | ```dart
57 | WPChessboard(
58 | size: size,
59 | orientation: orienatation,
60 | squareBuilder: squareBuilder,
61 | controller: controller,
62 | // Dont pass any onPieceDrop handler to disable drag and drop
63 | onPieceDrop: onPieceDrop,
64 | onPieceTap: onPieceTap,
65 | onPieceStartDrag: onPieceStartDrag,
66 | onEmptyFieldTap: onEmptyFieldTap,
67 | turnTopPlayerPieces: false,
68 | ghostOnDrag: true,
69 | dropIndicator: DropIndicatorArgs(
70 | size: size / 2,
71 | color: Colors.lightBlue.withOpacity(0.24)
72 | ),
73 | pieceMap: PieceMap(
74 | K: (size) => WhiteKing(size: size),
75 | Q: (size) => WhiteQueen(size: size),
76 | B: (size) => WhiteBishop(size: size),
77 | N: (size) => WhiteKnight(size: size),
78 | R: (size) => WhiteRook(size: size),
79 | P: (size) => WhitePawn(size: size),
80 | k: (size) => BlackKing(size: size),
81 | q: (size) => BlackQueen(size: size),
82 | b: (size) => BlackBishop(size: size),
83 | n: (size) => BlackKnight(size: size),
84 | r: (size) => BlackRook(size: size),
85 | p: (size) => BlackPawn(size: size),
86 | ),
87 | ),
88 | ```
89 |
90 | I know this is very short, for more information checkout the example :).
91 |
92 | ## Additional information
93 |
94 | Every contribution is very welcome.
95 |
96 | Cheers 🥂
97 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
3 | # Additional information about this file can be found at
4 | # https://dart.dev/guides/language/analysis-options
5 |
--------------------------------------------------------------------------------
/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: 7e9793dee1b85a243edd0e06cb1658e98b077561
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # example
2 |
3 | A new Flutter project.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/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 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/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 flutter.compileSdkVersion
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlinOptions {
37 | jvmTarget = '1.8'
38 | }
39 |
40 | sourceSets {
41 | main.java.srcDirs += 'src/main/kotlin'
42 | }
43 |
44 | defaultConfig {
45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
46 | applicationId "com.example.example"
47 | minSdkVersion flutter.minSdkVersion
48 | targetSdkVersion flutter.targetSdkVersion
49 | versionCode flutterVersionCode.toInteger()
50 | versionName flutterVersionName
51 | }
52 |
53 | buildTypes {
54 | release {
55 | // TODO: Add your own signing config for the release build.
56 | // Signing with the debug keys for now, so `flutter run --release` works.
57 | signingConfig signingConfigs.debug
58 | }
59 | }
60 | }
61 |
62 | flutter {
63 | source '../..'
64 | }
65 |
66 | dependencies {
67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
68 | }
69 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/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-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/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-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.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/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.6.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
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-6.7-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 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
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 "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
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 = 1300;
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 | INFOPLIST_FILE = Runner/Info.plist;
293 | LD_RUNPATH_SEARCH_PATHS = (
294 | "$(inherited)",
295 | "@executable_path/Frameworks",
296 | );
297 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
298 | PRODUCT_NAME = "$(TARGET_NAME)";
299 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
300 | SWIFT_VERSION = 5.0;
301 | VERSIONING_SYSTEM = "apple-generic";
302 | };
303 | name = Profile;
304 | };
305 | 97C147031CF9000F007C117D /* Debug */ = {
306 | isa = XCBuildConfiguration;
307 | buildSettings = {
308 | ALWAYS_SEARCH_USER_PATHS = NO;
309 | CLANG_ANALYZER_NONNULL = YES;
310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
311 | CLANG_CXX_LIBRARY = "libc++";
312 | CLANG_ENABLE_MODULES = YES;
313 | CLANG_ENABLE_OBJC_ARC = YES;
314 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
315 | CLANG_WARN_BOOL_CONVERSION = YES;
316 | CLANG_WARN_COMMA = YES;
317 | CLANG_WARN_CONSTANT_CONVERSION = YES;
318 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
319 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
320 | CLANG_WARN_EMPTY_BODY = YES;
321 | CLANG_WARN_ENUM_CONVERSION = YES;
322 | CLANG_WARN_INFINITE_RECURSION = YES;
323 | CLANG_WARN_INT_CONVERSION = YES;
324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
326 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
329 | CLANG_WARN_STRICT_PROTOTYPES = YES;
330 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
331 | CLANG_WARN_UNREACHABLE_CODE = YES;
332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
334 | COPY_PHASE_STRIP = NO;
335 | DEBUG_INFORMATION_FORMAT = dwarf;
336 | ENABLE_STRICT_OBJC_MSGSEND = YES;
337 | ENABLE_TESTABILITY = YES;
338 | GCC_C_LANGUAGE_STANDARD = gnu99;
339 | GCC_DYNAMIC_NO_PIC = NO;
340 | GCC_NO_COMMON_BLOCKS = YES;
341 | GCC_OPTIMIZATION_LEVEL = 0;
342 | GCC_PREPROCESSOR_DEFINITIONS = (
343 | "DEBUG=1",
344 | "$(inherited)",
345 | );
346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
348 | GCC_WARN_UNDECLARED_SELECTOR = YES;
349 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
350 | GCC_WARN_UNUSED_FUNCTION = YES;
351 | GCC_WARN_UNUSED_VARIABLE = YES;
352 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
353 | MTL_ENABLE_DEBUG_INFO = YES;
354 | ONLY_ACTIVE_ARCH = YES;
355 | SDKROOT = iphoneos;
356 | TARGETED_DEVICE_FAMILY = "1,2";
357 | };
358 | name = Debug;
359 | };
360 | 97C147041CF9000F007C117D /* Release */ = {
361 | isa = XCBuildConfiguration;
362 | buildSettings = {
363 | ALWAYS_SEARCH_USER_PATHS = NO;
364 | CLANG_ANALYZER_NONNULL = YES;
365 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
366 | CLANG_CXX_LIBRARY = "libc++";
367 | CLANG_ENABLE_MODULES = YES;
368 | CLANG_ENABLE_OBJC_ARC = YES;
369 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
370 | CLANG_WARN_BOOL_CONVERSION = YES;
371 | CLANG_WARN_COMMA = YES;
372 | CLANG_WARN_CONSTANT_CONVERSION = YES;
373 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
374 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
375 | CLANG_WARN_EMPTY_BODY = YES;
376 | CLANG_WARN_ENUM_CONVERSION = YES;
377 | CLANG_WARN_INFINITE_RECURSION = YES;
378 | CLANG_WARN_INT_CONVERSION = YES;
379 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
380 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
381 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
382 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
383 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
384 | CLANG_WARN_STRICT_PROTOTYPES = YES;
385 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
386 | CLANG_WARN_UNREACHABLE_CODE = YES;
387 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
388 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
389 | COPY_PHASE_STRIP = NO;
390 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
391 | ENABLE_NS_ASSERTIONS = NO;
392 | ENABLE_STRICT_OBJC_MSGSEND = YES;
393 | GCC_C_LANGUAGE_STANDARD = gnu99;
394 | GCC_NO_COMMON_BLOCKS = YES;
395 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
396 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
397 | GCC_WARN_UNDECLARED_SELECTOR = YES;
398 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
399 | GCC_WARN_UNUSED_FUNCTION = YES;
400 | GCC_WARN_UNUSED_VARIABLE = YES;
401 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
402 | MTL_ENABLE_DEBUG_INFO = NO;
403 | SDKROOT = iphoneos;
404 | SUPPORTED_PLATFORMS = iphoneos;
405 | SWIFT_COMPILATION_MODE = wholemodule;
406 | SWIFT_OPTIMIZATION_LEVEL = "-O";
407 | TARGETED_DEVICE_FAMILY = "1,2";
408 | VALIDATE_PRODUCT = YES;
409 | };
410 | name = Release;
411 | };
412 | 97C147061CF9000F007C117D /* Debug */ = {
413 | isa = XCBuildConfiguration;
414 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
415 | buildSettings = {
416 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
417 | CLANG_ENABLE_MODULES = YES;
418 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
419 | ENABLE_BITCODE = NO;
420 | INFOPLIST_FILE = Runner/Info.plist;
421 | LD_RUNPATH_SEARCH_PATHS = (
422 | "$(inherited)",
423 | "@executable_path/Frameworks",
424 | );
425 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
426 | PRODUCT_NAME = "$(TARGET_NAME)";
427 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
428 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
429 | SWIFT_VERSION = 5.0;
430 | VERSIONING_SYSTEM = "apple-generic";
431 | };
432 | name = Debug;
433 | };
434 | 97C147071CF9000F007C117D /* Release */ = {
435 | isa = XCBuildConfiguration;
436 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
437 | buildSettings = {
438 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
439 | CLANG_ENABLE_MODULES = YES;
440 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
441 | ENABLE_BITCODE = NO;
442 | INFOPLIST_FILE = Runner/Info.plist;
443 | LD_RUNPATH_SEARCH_PATHS = (
444 | "$(inherited)",
445 | "@executable_path/Frameworks",
446 | );
447 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
448 | PRODUCT_NAME = "$(TARGET_NAME)";
449 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
450 | SWIFT_VERSION = 5.0;
451 | VERSIONING_SYSTEM = "apple-generic";
452 | };
453 | name = Release;
454 | };
455 | /* End XCBuildConfiguration section */
456 |
457 | /* Begin XCConfigurationList section */
458 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
459 | isa = XCConfigurationList;
460 | buildConfigurations = (
461 | 97C147031CF9000F007C117D /* Debug */,
462 | 97C147041CF9000F007C117D /* Release */,
463 | 249021D3217E4FDB00AE95B9 /* Profile */,
464 | );
465 | defaultConfigurationIsVisible = 0;
466 | defaultConfigurationName = Release;
467 | };
468 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
469 | isa = XCConfigurationList;
470 | buildConfigurations = (
471 | 97C147061CF9000F007C117D /* Debug */,
472 | 97C147071CF9000F007C117D /* Release */,
473 | 249021D4217E4FDB00AE95B9 /* Profile */,
474 | );
475 | defaultConfigurationIsVisible = 0;
476 | defaultConfigurationName = Release;
477 | };
478 | /* End XCConfigurationList section */
479 | };
480 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
481 | }
482 |
--------------------------------------------------------------------------------
/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 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/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 | CFBundleDisplayName
8 | Example
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | example
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:chess/chess.dart' as Chess;
2 | import 'package:chess_vectors_flutter/chess_vectors_flutter.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:wp_chessboard/wp_chessboard.dart';
5 |
6 | void main() {
7 | runApp(const MyApp());
8 | }
9 |
10 | class MyApp extends StatefulWidget {
11 |
12 | const MyApp({Key? key}) : super(key: key);
13 |
14 | @override
15 | State createState() => _MyAppState();
16 | }
17 |
18 | class _MyAppState extends State {
19 | final controller = WPChessboardController();
20 | Chess.Chess chess = Chess.Chess();
21 | List>? lastMove;
22 |
23 | // not working on drop
24 | Widget squareBuilder(SquareInfo info) {
25 | Color fieldColor = (info.index + info.rank) % 2 == 0 ? Colors.grey.shade200 : Colors.grey.shade600;
26 | Color overlayColor = Colors.transparent;
27 |
28 | if (lastMove != null ) {
29 | if (lastMove!.first.first == info.rank && lastMove!.first.last == info.file) {
30 | overlayColor = Colors.blueAccent.shade400.withOpacity(0.4);
31 | } else if (lastMove!.last.first == info.rank && lastMove!.last.last == info.file) {
32 | overlayColor = Colors.blueAccent.shade400.withOpacity(0.87);
33 | }
34 | }
35 |
36 | return Container(
37 | color: fieldColor,
38 | width: info.size,
39 | height: info.size,
40 | child: AnimatedContainer(
41 | color: overlayColor,
42 | width: info.size,
43 | height: info.size,
44 | duration: const Duration(milliseconds: 200),
45 | )
46 | );
47 | }
48 |
49 | void onPieceStartDrag(SquareInfo square, String piece) {
50 | showHintFields(square, piece);
51 | }
52 |
53 | void onPieceTap(SquareInfo square, String piece) {
54 | if (controller.hints.key == square.index.toString()) {
55 | controller.setHints(HintMap());
56 | return;
57 | }
58 | showHintFields(square, piece);
59 | }
60 |
61 | void showHintFields(SquareInfo square, String piece) {
62 | final moves = chess.generate_moves({ 'square': square.toString() });
63 | final hintMap = HintMap(key: square.index.toString());
64 | for (var move in moves) {
65 | String to = move.toAlgebraic;
66 | int rank = to.codeUnitAt(1) - "1".codeUnitAt(0) + 1;
67 | int file = to.codeUnitAt(0) - "a".codeUnitAt(0) + 1;
68 |
69 | hintMap.set(rank, file, (size) => MoveHint(
70 | size: size,
71 | onPressed: () => doMove(move),
72 | ));
73 | }
74 | controller.setHints(hintMap);
75 | }
76 |
77 | void onEmptyFieldTap(SquareInfo square) {
78 | controller.setHints(HintMap());
79 | }
80 |
81 | void onPieceDrop(PieceDropEvent event) {
82 | chess.move({ "from": event.from.toString(), "to": event.to.toString() });
83 |
84 | lastMove = [
85 | [ event.from.rank, event.from.file ],
86 | [ event.to.rank, event.to.file ]
87 | ];
88 |
89 | update(animated: false);
90 | }
91 |
92 | void doMove(Chess.Move move) {
93 | chess.move(move);
94 |
95 | int rankFrom = move.fromAlgebraic.codeUnitAt(1) - "1".codeUnitAt(0) + 1;
96 | int fileFrom = move.fromAlgebraic.codeUnitAt(0) - "a".codeUnitAt(0) + 1;
97 | int rankTo = move.toAlgebraic.codeUnitAt(1) - "1".codeUnitAt(0) + 1;
98 | int fileTo = move.toAlgebraic.codeUnitAt(0) - "a".codeUnitAt(0) + 1;
99 | lastMove = [
100 | [ rankFrom, fileFrom ],
101 | [ rankTo, fileTo ]
102 | ];
103 |
104 | update();
105 | }
106 | void setDefaultFen() {
107 | setState(() {
108 | chess = Chess.Chess.fromFEN("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
109 | });
110 | update();
111 | }
112 |
113 | void setRandomFen() {
114 | setState(() {
115 | chess = Chess.Chess.fromFEN("3bK3/4B1P1/3p2N1/1rp3P1/2p2p2/p3n3/P5k1/6q1 w - - 0 1");
116 | });
117 | update();
118 | }
119 |
120 | void update({bool animated = true}) {
121 | controller.setFen(chess.fen, animation: animated);
122 | }
123 |
124 | void addArrows() {
125 | controller.setArrows([
126 | Arrow(
127 | from: SquareLocation.fromString("b1"),
128 | to: SquareLocation.fromString("c3"),
129 | ),
130 | Arrow(
131 | from: SquareLocation.fromString("g1"),
132 | to: SquareLocation.fromString("f3"),
133 | color: Colors.red
134 | )
135 | ]);
136 | }
137 |
138 | void removeArrows() {
139 | controller.setArrows([]);
140 | }
141 |
142 | BoardOrientation orienatation = BoardOrientation.white;
143 | void toggleArrows() {
144 | setState(() {
145 | if (orienatation == BoardOrientation.white) {
146 | orienatation = BoardOrientation.black;
147 | } else {
148 | orienatation = BoardOrientation.white;
149 | }
150 | });
151 | }
152 |
153 | @override
154 | Widget build(BuildContext context) {
155 | return MaterialApp(
156 | title: 'WPChessboard Demo',
157 | home: Scaffold(
158 | body: Builder(builder: (context) {
159 | final double size = MediaQuery.of(context).size.shortestSide;
160 | return Column(
161 | mainAxisAlignment: MainAxisAlignment.center,
162 | children: [
163 | WPChessboard(
164 | size: size,
165 | orientation: orienatation,
166 | squareBuilder: squareBuilder,
167 | controller: controller,
168 | // Dont pass any onPieceDrop handler to disable drag and drop
169 | onPieceDrop: onPieceDrop,
170 | onPieceTap: onPieceTap,
171 | onPieceStartDrag: onPieceStartDrag,
172 | onEmptyFieldTap: onEmptyFieldTap,
173 | turnTopPlayerPieces: false,
174 | ghostOnDrag: true,
175 | dropIndicator: DropIndicatorArgs(
176 | size: size / 2,
177 | color: Colors.lightBlue.withOpacity(0.24)
178 | ),
179 | pieceMap: PieceMap(
180 | K: (size) => WhiteKing(size: size),
181 | Q: (size) => WhiteQueen(size: size),
182 | B: (size) => WhiteBishop(size: size),
183 | N: (size) => WhiteKnight(size: size),
184 | R: (size) => WhiteRook(size: size),
185 | P: (size) => WhitePawn(size: size),
186 | k: (size) => BlackKing(size: size),
187 | q: (size) => BlackQueen(size: size),
188 | b: (size) => BlackBishop(size: size),
189 | n: (size) => BlackKnight(size: size),
190 | r: (size) => BlackRook(size: size),
191 | p: (size) => BlackPawn(size: size),
192 | ),
193 | ),
194 | const SizedBox(height: 24),
195 | TextButton(
196 | onPressed: setDefaultFen,
197 | child: const Text("Set default Fen"),
198 | ),
199 | TextButton(
200 | onPressed: setRandomFen,
201 | child: const Text("Set random Fen"),
202 | ),
203 | TextButton(
204 | onPressed: addArrows,
205 | child: const Text("Add Arrows"),
206 | ),
207 | TextButton(
208 | onPressed: removeArrows,
209 | child: const Text("Remove Arrows"),
210 | ),
211 | TextButton(
212 | onPressed: toggleArrows,
213 | child: const Text("Change Orientation"),
214 | )
215 | ],
216 | );
217 | },
218 | )
219 | )
220 | );
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/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 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.8.2"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "2.1.0"
18 | characters:
19 | dependency: transitive
20 | description:
21 | name: characters
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "1.2.0"
25 | charcode:
26 | dependency: transitive
27 | description:
28 | name: charcode
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.3.1"
32 | chess:
33 | dependency: "direct main"
34 | description:
35 | name: chess
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "0.7.0"
39 | chess_vectors_flutter:
40 | dependency: "direct main"
41 | description:
42 | name: chess_vectors_flutter
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.0.16"
46 | clock:
47 | dependency: transitive
48 | description:
49 | name: clock
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "1.1.0"
53 | collection:
54 | dependency: transitive
55 | description:
56 | name: collection
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "1.16.0"
60 | cupertino_icons:
61 | dependency: "direct main"
62 | description:
63 | name: cupertino_icons
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "1.0.4"
67 | fake_async:
68 | dependency: transitive
69 | description:
70 | name: fake_async
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "1.3.0"
74 | flutter:
75 | dependency: "direct main"
76 | description: flutter
77 | source: sdk
78 | version: "0.0.0"
79 | flutter_lints:
80 | dependency: "direct dev"
81 | description:
82 | name: flutter_lints
83 | url: "https://pub.dartlang.org"
84 | source: hosted
85 | version: "1.0.4"
86 | flutter_test:
87 | dependency: "direct dev"
88 | description: flutter
89 | source: sdk
90 | version: "0.0.0"
91 | lints:
92 | dependency: transitive
93 | description:
94 | name: lints
95 | url: "https://pub.dartlang.org"
96 | source: hosted
97 | version: "1.0.1"
98 | matcher:
99 | dependency: transitive
100 | description:
101 | name: matcher
102 | url: "https://pub.dartlang.org"
103 | source: hosted
104 | version: "0.12.11"
105 | material_color_utilities:
106 | dependency: transitive
107 | description:
108 | name: material_color_utilities
109 | url: "https://pub.dartlang.org"
110 | source: hosted
111 | version: "0.1.4"
112 | meta:
113 | dependency: transitive
114 | description:
115 | name: meta
116 | url: "https://pub.dartlang.org"
117 | source: hosted
118 | version: "1.7.0"
119 | path:
120 | dependency: transitive
121 | description:
122 | name: path
123 | url: "https://pub.dartlang.org"
124 | source: hosted
125 | version: "1.8.1"
126 | quiver:
127 | dependency: transitive
128 | description:
129 | name: quiver
130 | url: "https://pub.dartlang.org"
131 | source: hosted
132 | version: "3.0.1+1"
133 | sky_engine:
134 | dependency: transitive
135 | description: flutter
136 | source: sdk
137 | version: "0.0.99"
138 | source_span:
139 | dependency: transitive
140 | description:
141 | name: source_span
142 | url: "https://pub.dartlang.org"
143 | source: hosted
144 | version: "1.8.2"
145 | stack_trace:
146 | dependency: transitive
147 | description:
148 | name: stack_trace
149 | url: "https://pub.dartlang.org"
150 | source: hosted
151 | version: "1.10.0"
152 | stream_channel:
153 | dependency: transitive
154 | description:
155 | name: stream_channel
156 | url: "https://pub.dartlang.org"
157 | source: hosted
158 | version: "2.1.0"
159 | string_scanner:
160 | dependency: transitive
161 | description:
162 | name: string_scanner
163 | url: "https://pub.dartlang.org"
164 | source: hosted
165 | version: "1.1.0"
166 | term_glyph:
167 | dependency: transitive
168 | description:
169 | name: term_glyph
170 | url: "https://pub.dartlang.org"
171 | source: hosted
172 | version: "1.2.0"
173 | test_api:
174 | dependency: transitive
175 | description:
176 | name: test_api
177 | url: "https://pub.dartlang.org"
178 | source: hosted
179 | version: "0.4.9"
180 | tuple:
181 | dependency: transitive
182 | description:
183 | name: tuple
184 | url: "https://pub.dartlang.org"
185 | source: hosted
186 | version: "2.0.0"
187 | vector_math:
188 | dependency: transitive
189 | description:
190 | name: vector_math
191 | url: "https://pub.dartlang.org"
192 | source: hosted
193 | version: "2.1.2"
194 | wp_chessboard:
195 | dependency: "direct main"
196 | description:
197 | path: ".."
198 | relative: true
199 | source: path
200 | version: "0.0.3"
201 | sdks:
202 | dart: ">=2.17.0-0 <3.0.0"
203 | flutter: ">=1.17.0"
204 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: example
2 | description: A new Flutter project.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `flutter pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | environment:
21 | sdk: ">=2.16.1 <3.0.0"
22 |
23 | # Dependencies specify other packages that your package needs in order to work.
24 | # To automatically upgrade your package dependencies to the latest versions
25 | # consider running `flutter pub upgrade --major-versions`. Alternatively,
26 | # dependencies can be manually updated by changing the version numbers below to
27 | # the latest version available on pub.dev. To see which dependencies have newer
28 | # versions available, run `flutter pub outdated`.
29 | dependencies:
30 | flutter:
31 | sdk: flutter
32 | wp_chessboard:
33 | path: "../"
34 | chess_vectors_flutter: ^1.0.18
35 | chess: ^0.7.0
36 |
37 |
38 | # The following adds the Cupertino Icons font to your application.
39 | # Use with the CupertinoIcons class for iOS style icons.
40 | cupertino_icons: ^1.0.2
41 |
42 | dev_dependencies:
43 | flutter_test:
44 | sdk: flutter
45 |
46 | # The "flutter_lints" package below contains a set of recommended lints to
47 | # encourage good coding practices. The lint set provided by the package is
48 | # activated in the `analysis_options.yaml` file located at the root of your
49 | # package. See that file for information about deactivating specific lint
50 | # rules and activating additional ones.
51 | flutter_lints: ^1.0.0
52 |
53 | # For information on the generic Dart part of this file, see the
54 | # following page: https://dart.dev/tools/pub/pubspec
55 |
56 | # The following section is specific to Flutter.
57 | flutter:
58 |
59 | # The following line ensures that the Material Icons font is
60 | # included with your application, so that you can use the icons in
61 | # the material Icons class.
62 | uses-material-design: true
63 |
64 | # To add assets to your application, add an assets section, like this:
65 | # assets:
66 | # - images/a_dot_burr.jpeg
67 | # - images/a_dot_ham.jpeg
68 |
69 | # An image asset can refer to one or more resolution-specific "variants", see
70 | # https://flutter.dev/assets-and-images/#resolution-aware.
71 |
72 | # For details regarding adding assets from package dependencies, see
73 | # https://flutter.dev/assets-and-images/#from-packages
74 |
75 | # To add custom fonts to your application, add a fonts section here,
76 | # in this "flutter" section. Each entry in this list should have a
77 | # "family" key with the font family name, and a "fonts" key with a
78 | # list giving the asset and other descriptors for the font. For
79 | # example:
80 | # fonts:
81 | # - family: Schyler
82 | # fonts:
83 | # - asset: fonts/Schyler-Regular.ttf
84 | # - asset: fonts/Schyler-Italic.ttf
85 | # style: italic
86 | # - family: Trajan Pro
87 | # fonts:
88 | # - asset: fonts/TrajanPro.ttf
89 | # - asset: fonts/TrajanPro_Bold.ttf
90 | # weight: 700
91 | #
92 | # For details regarding fonts from package dependencies,
93 | # see https://flutter.dev/custom-fonts/#from-packages
94 |
--------------------------------------------------------------------------------
/images/animate-many.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/images/animate-many.gif
--------------------------------------------------------------------------------
/images/animate-single.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/images/animate-single.gif
--------------------------------------------------------------------------------
/images/board-arrows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/images/board-arrows.png
--------------------------------------------------------------------------------
/images/board-orientation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/images/board-orientation.png
--------------------------------------------------------------------------------
/images/board.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/images/board.png
--------------------------------------------------------------------------------
/images/drag-drop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/images/drag-drop.png
--------------------------------------------------------------------------------
/images/hints.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/images/hints.gif
--------------------------------------------------------------------------------
/lib/components/animated_piece_wrap.dart:
--------------------------------------------------------------------------------
1 | library wp_chessboard;
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:wp_chessboard/models/chess_state.dart';
5 |
6 | class AnimatedPieceWrap extends StatefulWidget {
7 | final Widget child;
8 | final StateEntry stateEntry;
9 | final double squareSize;
10 | final bool animated;
11 |
12 | const AnimatedPieceWrap({Key? key, required this.child, required this.stateEntry, required this.squareSize, required this.animated}) : super(key: key);
13 |
14 | @override
15 | State createState() => _AnimatedPieceWrapState();
16 | }
17 |
18 | class _AnimatedPieceWrapState extends State {
19 | int rank = 0;
20 | int file = 0;
21 |
22 | @override
23 | void initState() {
24 | if (widget.animated) {
25 | SquarePosition? pos = widget.stateEntry.lastPosition();
26 | if (pos != null) {
27 | rank = pos.rank;
28 | file = pos.file;
29 | } else {
30 | rank = widget.stateEntry.position.rank;
31 | file = widget.stateEntry.position.file;
32 | }
33 | WidgetsBinding.instance!.addPostFrameCallback((_) {
34 | setState(() {
35 | rank = widget.stateEntry.position.rank;
36 | file = widget.stateEntry.position.file;
37 | });
38 | });
39 | } else {
40 | rank = widget.stateEntry.position.rank;
41 | file = widget.stateEntry.position.file;
42 | }
43 |
44 | super.initState();
45 | }
46 |
47 | @override
48 | Widget build(BuildContext context) {
49 | double left = (file) * widget.squareSize;
50 | double bottom = (rank) * widget.squareSize;
51 |
52 | return AnimatedPositioned(
53 | key: Key(widget.stateEntry.getKey() + "_a"),
54 | curve: Curves.easeInOut,
55 | duration: const Duration(milliseconds: 200),
56 | bottom: bottom,
57 | left: left,
58 | child: widget.child
59 | );
60 | }
61 | }
--------------------------------------------------------------------------------
/lib/components/arrows.dart:
--------------------------------------------------------------------------------
1 | library wp_chessboard;
2 |
3 | import 'dart:math';
4 | import 'dart:ui';
5 |
6 | import 'package:flutter/material.dart';
7 | import 'package:wp_chessboard/models/arrow.dart';
8 | import 'package:wp_chessboard/models/square.dart';
9 |
10 | class Arrows extends StatelessWidget {
11 | final double size;
12 | final List arrows;
13 |
14 | const Arrows({Key? key, required this.size, required this.arrows}) : super(key: key);
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | return IgnorePointer(
19 | child: CustomPaint(
20 | painter: ArrowPainter(arrows, size),
21 | size: Size(size, size),
22 | )
23 | );
24 | }
25 |
26 | }
27 |
28 | class ArrowPainter extends CustomPainter {
29 | final double size;
30 | final List arrows;
31 |
32 | ArrowPainter(this.arrows, this.size);
33 |
34 | Offset getPosition(SquareLocation loc) {
35 | double squareSize = size / 8;
36 |
37 | return Offset(
38 | loc.fileIndex * squareSize + (squareSize / 2),
39 | size - loc.rankIndex * squareSize - (squareSize / 2),
40 | );
41 | }
42 |
43 | @override
44 | void paint(Canvas canvas, Size size) {
45 | for (Arrow arrow in arrows) {
46 |
47 | double squareWidth = size.width / 8;
48 | double arrowHeadLen = squareWidth * 0.24;
49 | PointMode pointMode = PointMode.polygon;
50 | Offset from = getPosition(arrow.from);
51 | Offset to = getPosition(arrow.to);
52 | ParagraphBuilder labelBuilder = ParagraphBuilder(ParagraphStyle(
53 | textAlign: TextAlign.center,
54 | fontSize: 12,
55 | fontWeight: FontWeight.bold,
56 | ));
57 |
58 | // Line
59 | double angle = atan2(to.dy - from.dy, to.dx - from.dx);
60 | Paint linePaint = Paint()
61 | ..color = arrow.color
62 | ..strokeWidth = 4
63 | ..strokeCap = StrokeCap.round;
64 | canvas.drawPoints(pointMode, [from, to], linePaint);
65 |
66 | // Arrow
67 | canvas.drawPoints(pointMode, [Offset(to.dx - arrowHeadLen * cos(angle - pi / 6), to.dy - arrowHeadLen * sin(angle - pi / 6)), to], linePaint);
68 | canvas.drawPoints(pointMode, [Offset(to.dx - arrowHeadLen * cos(angle + pi / 6), to.dy - arrowHeadLen * sin(angle + pi / 6)), to], linePaint);
69 |
70 | // Circle
71 | // Paint circlePaint1 = Paint()..color = arrow.color;
72 | // Paint circlePaint2 = Paint()..color = Colors.white;
73 | // canvas.drawCircle(to, 14, circlePaint1);
74 | // canvas.drawCircle(to, 10, circlePaint2);
75 |
76 | canvas.drawParagraph(
77 | labelBuilder.build()
78 | ..layout(ParagraphConstraints(width: squareWidth)),
79 | Offset(to.dx - (squareWidth / 2), to.dy - 6));
80 | }
81 | }
82 |
83 | @override
84 | bool shouldRepaint(covariant CustomPainter oldDelegate) {
85 | return true;
86 | }
87 | }
--------------------------------------------------------------------------------
/lib/components/drop_targets.dart:
--------------------------------------------------------------------------------
1 | library wp_chessboard;
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:wp_chessboard/models/drop_indicator_args.dart';
5 | import 'package:wp_chessboard/models/piece_drop_event.dart';
6 | import 'package:wp_chessboard/models/square_info.dart';
7 |
8 | class DropTargets extends StatefulWidget {
9 | final double size;
10 | final DropIndicatorArgs? dropIndicator;
11 | final void Function(PieceDropEvent)? onPieceDrop;
12 |
13 |
14 | const DropTargets({Key? key, required this.size, this.onPieceDrop, this.dropIndicator}) : super(key: key);
15 |
16 | @override
17 | State createState() => _DropTargetsState();
18 | }
19 |
20 | class _DropTargetsState extends State {
21 | SquareInfo? dropHover;
22 |
23 | void onMove(SquareInfo square, SquareInfo data) {
24 | if (data.index == square.index) {
25 | if (dropHover == null) return;
26 | setState(() {
27 | dropHover = null;
28 | });
29 | return;
30 | }
31 |
32 | if (dropHover == null || dropHover!.index != square.index) {
33 | setState(() {
34 | dropHover = square;
35 | });
36 | }
37 | }
38 |
39 | void onLeave(SquareInfo square) {
40 | if (dropHover != null && dropHover!.index == square.index) {
41 | setState(() {
42 | dropHover = null;
43 | });
44 | }
45 | }
46 |
47 | @override
48 | Widget build(BuildContext context) {
49 | double squareSize = widget.size / 8;
50 |
51 | return Stack(
52 | children: [
53 |
54 | Builder(
55 | builder: (context) {
56 | if (widget.dropIndicator == null || dropHover == null) return const SizedBox();
57 |
58 | double left = (dropHover!.file - 1) * squareSize + squareSize / 2 - (widget.dropIndicator!.size / 2);
59 | double bottom = (dropHover!.rank - 1) * squareSize + squareSize / 2 - (widget.dropIndicator!.size / 2);
60 |
61 | return Positioned(
62 | bottom: bottom,
63 | left: left,
64 | child: IgnorePointer(
65 | child: Container(
66 | width: widget.dropIndicator!.size,
67 | height: widget.dropIndicator!.size,
68 | decoration: BoxDecoration(
69 | borderRadius: widget.dropIndicator!.radius,
70 | color: widget.dropIndicator!.color,
71 | ),
72 | ),
73 | )
74 | );
75 | },
76 | ),
77 |
78 | ...(List.generate(64, (i) => i + 1)).map(
79 | (i) {
80 | SquareInfo info = SquareInfo(i - 1, squareSize);
81 |
82 | double left = (info.file - 1) * squareSize;
83 | double bottom = (info.rank - 1) * squareSize;
84 |
85 | return Positioned(
86 | bottom: bottom,
87 | left: left,
88 | child: DragTarget(
89 | onWillAccept: (data) {
90 | return data != null && data.index != info.index;
91 | },
92 | onAccept: (data) {
93 | onLeave(info);
94 | if (widget.onPieceDrop != null) {
95 | widget.onPieceDrop!(PieceDropEvent(data, info));
96 | }
97 | },
98 | onMove: (data) => onMove(info, data.data),
99 | onLeave: (data) => onLeave(info),
100 | builder: (
101 | (context, candidateData, rejectedData) => SizedBox(width: squareSize, height: squareSize)
102 | ),
103 | ),
104 | );
105 | }
106 | ).toList(),
107 |
108 | ]
109 | );
110 | }
111 | }
--------------------------------------------------------------------------------
/lib/components/hints.dart:
--------------------------------------------------------------------------------
1 | library wp_chessboard;
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:wp_chessboard/models/hint_map.dart';
5 | import 'package:wp_chessboard/models/square_info.dart';
6 |
7 | class Hints extends StatelessWidget {
8 | final double size;
9 | final HintMap hints;
10 |
11 | const Hints({Key? key, required this.size, required this.hints}) : super(key: key);
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | double squareSize = size / 8;
16 |
17 | return Stack(
18 | children: (List.generate(64, (i) => i + 1)).map(
19 | (i) {
20 | SquareInfo info = SquareInfo(i - 1, squareSize);
21 |
22 | double left = (info.file - 1) * squareSize;
23 | double bottom = (info.rank - 1) * squareSize;
24 |
25 | HintBuilder? hint = hints.getHint(info.rank, info.file);
26 |
27 | return Positioned(
28 | bottom: bottom,
29 | left: left,
30 | child: hint != null ? hint(squareSize) : const SizedBox(),
31 | );
32 | }
33 | ).toList(),
34 | );
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/lib/components/hints/move_hint.dart:
--------------------------------------------------------------------------------
1 | library wp_chessboard;
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class MoveHint extends StatelessWidget {
6 | final double size;
7 | final Color color;
8 | final VoidCallback? onPressed;
9 |
10 | const MoveHint({Key? key, required this.size, this.color = Colors.tealAccent, this.onPressed}) : super(key: key);
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | double hintSize = size * 0.2;
15 |
16 | return GestureDetector(
17 | onTapDown: onPressed != null ? (_) => onPressed!() : null,
18 | child: Container(
19 | width: size,
20 | height: size,
21 | color: Colors.transparent,
22 | child: Column(
23 | mainAxisAlignment: MainAxisAlignment.center,
24 | crossAxisAlignment: CrossAxisAlignment.center,
25 | children: [
26 | Container(
27 | width: hintSize,
28 | height: hintSize,
29 | decoration: BoxDecoration(
30 | color: color,
31 | borderRadius: BorderRadius.circular(hintSize)
32 | ),
33 | )
34 | ],
35 | ),
36 | )
37 | );
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/lib/components/pieces.dart:
--------------------------------------------------------------------------------
1 | library wp_chessboard;
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:wp_chessboard/components/animated_piece_wrap.dart';
5 | import 'package:wp_chessboard/models/board_orientation.dart';
6 | import 'package:wp_chessboard/models/chess_state.dart';
7 | import 'package:wp_chessboard/models/piece_map.dart';
8 | import 'package:wp_chessboard/models/square_info.dart';
9 |
10 | class Pieces extends StatelessWidget {
11 | final double size;
12 | final PieceMap pieceMap;
13 | final ChessState state;
14 | final BoardOrientation orientation;
15 | final void Function(SquareInfo square, String piece)? onPieceTap;
16 | final void Function(SquareInfo square, String piece)? onPieceStartDrag;
17 | final void Function(SquareInfo square)? onEmptyFieldTap;
18 | final bool animated;
19 | final bool disableDrag;
20 | final bool ghostOnDrag;
21 | final bool turnTopPlayerPieces;
22 |
23 | const Pieces({Key? key, required this.size, required this.pieceMap, required this.state, this.onPieceTap, this.onEmptyFieldTap, this.onPieceStartDrag, required this.animated, required this.orientation, required this.disableDrag, required this.ghostOnDrag, required this.turnTopPlayerPieces}) : super(key: key);
24 |
25 | @override
26 | Widget build(BuildContext context) {
27 | double squareSize = size / 8;
28 |
29 | return Stack(
30 | children: (List.generate(64, (i) => i + 1)).map(
31 | (i) {
32 | SquareInfo info = SquareInfo(i - 1, squareSize);
33 | StateEntry pieceEntry = state.getEntry(info.rank, info.file);
34 |
35 | double left = (info.file - 1) * squareSize;
36 | double bottom = (info.rank - 1) * squareSize;
37 |
38 | if (pieceEntry.piece == "") {
39 | return Positioned(
40 | key: Key("piece_" + info.toString() + "_none"),
41 | bottom: bottom,
42 | left: left,
43 | child: GestureDetector(
44 | onTapDown: onEmptyFieldTap != null ? (_) => onEmptyFieldTap!(info) : null,
45 | child: Container(
46 | color: Colors.transparent,
47 | width: squareSize,
48 | height: squareSize,
49 | )
50 | ),
51 | );
52 | }
53 |
54 | Widget pieceWidget = pieceMap.get(pieceEntry.piece)(squareSize);
55 |
56 | bool isBlackPiece = pieceEntry.piece.toLowerCase() == pieceEntry.piece;
57 | bool shouldTurnPiece = turnTopPlayerPieces && (
58 | (orientation == BoardOrientation.black && !isBlackPiece)
59 | || (orientation == BoardOrientation.white && isBlackPiece)
60 | );
61 |
62 | return AnimatedPieceWrap(
63 | key: Key(pieceEntry.getKey()),
64 | squareSize: squareSize,
65 | stateEntry: pieceEntry,
66 | animated: animated,
67 | child: GestureDetector(
68 | onTapDown: onPieceTap != null ? (_) => onPieceTap!(info, pieceEntry.piece) : null,
69 | child: RotatedBox(
70 | quarterTurns: ((orientation == BoardOrientation.black) ? 2 : 0) + (shouldTurnPiece ? 2 : 0),
71 | child: disableDrag ? pieceWidget : Draggable(
72 | onDragStarted: onPieceStartDrag != null ? () => onPieceStartDrag!(info, pieceEntry.piece) : null,
73 | childWhenDragging: ghostOnDrag ? Opacity(opacity: 0.2, child: pieceWidget) : const SizedBox(),
74 | data: info,
75 | feedback: pieceWidget,
76 | child: pieceWidget,
77 | )
78 | ),
79 | ),
80 | );
81 | }
82 | ).toList(),
83 | );
84 | }
85 |
86 | }
--------------------------------------------------------------------------------
/lib/components/squares.dart:
--------------------------------------------------------------------------------
1 | library wp_chessboard;
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:wp_chessboard/models/square_info.dart';
5 |
6 | class Squares extends StatelessWidget {
7 | final double size;
8 | final Widget Function(SquareInfo) squareBuilder;
9 |
10 | const Squares({Key? key, required this.size, required this.squareBuilder}) : super(key: key);
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | double squareSize = size / 8;
15 |
16 | return Stack(
17 | children: (List.generate(64, (i) => i + 1)).map(
18 | (i) {
19 | SquareInfo info = SquareInfo(i - 1, squareSize);
20 |
21 | double left = (info.file - 1) * squareSize;
22 | double bottom = (info.rank - 1) * squareSize;
23 |
24 | return Positioned(
25 | bottom: bottom,
26 | left: left,
27 | child: squareBuilder(info)
28 | );
29 | }
30 | ).toList(),
31 | );
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/lib/models/arrow.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:wp_chessboard/models/square.dart';
3 |
4 | class Arrow {
5 | final SquareLocation from;
6 | final SquareLocation to;
7 | final Color color;
8 |
9 | Arrow({required this.from, required this.to, this.color = Colors.green});
10 | }
--------------------------------------------------------------------------------
/lib/models/arrow_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:wp_chessboard/models/arrow.dart';
2 |
3 | class ArrowList {
4 | static int _lastId = 0;
5 | late int _id;
6 |
7 | final List value;
8 |
9 | int get id {
10 | return _id;
11 | }
12 |
13 | ArrowList(this.value) {
14 | _updateId();
15 | }
16 |
17 | void _updateId() {
18 | _id = _lastId++;
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/lib/models/board_orientation.dart:
--------------------------------------------------------------------------------
1 | enum BoardOrientation {
2 | white, black
3 | }
--------------------------------------------------------------------------------
/lib/models/chess_state.dart:
--------------------------------------------------------------------------------
1 | enum StateEntryDelta {
2 | removed, none, added, replaced
3 | }
4 |
5 | class StateEntry {
6 | final String piece;
7 | final SquarePosition position;
8 | final ChessState state;
9 |
10 | StateEntry(this.piece, this.position, this.state);
11 |
12 | SquarePosition? lastPosition() {
13 | StateEntryDelta delta = state.getDelta(piece, state.last?.board[position.rank]?[position.file]?.piece ?? "");
14 | return delta == StateEntryDelta.added || delta == StateEntryDelta.replaced ? state.findFrom(piece) : null;
15 | }
16 |
17 | String getKey() {
18 | return "ste_" + position.toString() + "_" + piece;
19 | }
20 | }
21 |
22 | class SquarePosition {
23 | final int rank;
24 | final int file;
25 |
26 | SquarePosition(this.rank, this.file);
27 |
28 | @override
29 | String toString() {
30 | return rank.toString() + file.toString();
31 | }
32 | }
33 |
34 | class ChessState {
35 | static int zero = "0".codeUnitAt(0);
36 | static int nine = "9".codeUnitAt(0);
37 | static int space = " ".codeUnitAt(0);
38 |
39 | final ChessState? last;
40 | final String fen;
41 | late final Map> board;
42 |
43 | ChessState(this.fen, { this.last }) {
44 | Map> _board = {};
45 |
46 | if (fen == "") {
47 | for (var i = 0; i < 8; i++) {
48 | _board[i] = {};
49 | for (var j = 0; j < 8; j++) {
50 | _board[i]![j] = StateEntry("", SquarePosition(i, j), this);
51 | }
52 | }
53 | } else {
54 | int rank = 0;
55 | for (var fenRank in fen.split("/")) {
56 | int file = 0;
57 | int currRank = 7 - rank;
58 | _board[currRank] = {};
59 |
60 | for (var i = 0; i < fenRank.length; i++) {
61 | int piece = fenRank.codeUnitAt(i);
62 | if (piece == space) break;
63 |
64 | if (piece >= zero && piece <= nine) {
65 | for (int j = 0; j < piece-zero; j++) {
66 | _board[currRank]![file] = StateEntry("", SquarePosition(currRank, file), this);
67 | file++;
68 | }
69 | } else {
70 | String pieceNotation = String.fromCharCode(piece);
71 | _board[currRank]![file] = StateEntry(pieceNotation, SquarePosition(currRank, file), this);
72 | file++;
73 | }
74 | }
75 | rank++;
76 | }
77 | }
78 |
79 | board = _board;
80 | }
81 |
82 | StateEntryDelta getDelta(String piece, String lastPiece) {
83 | if (piece == lastPiece) return StateEntryDelta.none;
84 | if (lastPiece == "") return StateEntryDelta.added;
85 | if (piece == "") return StateEntryDelta.removed;
86 | return StateEntryDelta.replaced;
87 | }
88 |
89 | StateEntry getEntry(int rank, int file) {
90 | return board[rank-1]![file-1]!;
91 | }
92 |
93 | SquarePosition? findFrom(String piece) {
94 | if (last == null) {
95 | return null;
96 | }
97 |
98 | for (var rank in board.entries) {
99 | for (var file in rank.value.entries) {
100 | if (file.value.piece == "" && last!.board[rank.key]![file.key]!.piece == piece) {
101 | return SquarePosition(rank.key, file.key);
102 | }
103 | }
104 | }
105 | return null;
106 | }
107 |
108 | }
--------------------------------------------------------------------------------
/lib/models/drop_indicator_args.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DropIndicatorArgs {
4 | final double size;
5 | final Color color;
6 | final BorderRadius radius;
7 |
8 | DropIndicatorArgs({required this.size, required this.color, radius}) : radius = radius ?? BorderRadius.circular(size);
9 | }
--------------------------------------------------------------------------------
/lib/models/hint_map.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | typedef HintBuilder = Widget Function(double size);
4 |
5 | class HintMap {
6 | static int _lastId = 0;
7 | final String key;
8 | late int _id;
9 | Map> board = {};
10 |
11 | int get id {
12 | return _id;
13 | }
14 |
15 | HintMap({ this.key = "" }) {
16 | _updateId();
17 | for (var i = 0; i < 8; i++) {
18 | board[i] = {};
19 | for (var j = 0; j < 8; j++) {
20 | board[i]![j] = null;
21 | }
22 | }
23 | }
24 |
25 | void _updateId() {
26 | _id = _lastId++;
27 | }
28 |
29 | HintMap set(int rank, int file, HintBuilder? widget) {
30 | board[rank-1]![file-1] = widget;
31 | return this;
32 | }
33 |
34 | HintBuilder? getHint(int rank, int file) {
35 | return board[rank-1]![file-1];
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/lib/models/piece_drop_event.dart:
--------------------------------------------------------------------------------
1 | import 'package:wp_chessboard/models/square_info.dart';
2 |
3 | class PieceDropEvent {
4 | final SquareInfo from;
5 | final SquareInfo to;
6 |
7 | PieceDropEvent(this.from, this.to);
8 | }
--------------------------------------------------------------------------------
/lib/models/piece_map.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | typedef PieceBuilder = Widget Function(double size);
4 |
5 | class PieceMap {
6 | final PieceBuilder K;
7 | final PieceBuilder Q;
8 | final PieceBuilder B;
9 | final PieceBuilder N;
10 | final PieceBuilder R;
11 | final PieceBuilder P;
12 |
13 | final PieceBuilder k;
14 | final PieceBuilder q;
15 | final PieceBuilder b;
16 | final PieceBuilder n;
17 | final PieceBuilder r;
18 | final PieceBuilder p;
19 |
20 | PieceMap({required this.K, required this.Q, required this.B, required this.N, required this.R, required this.P, required this.k, required this.q, required this.b, required this.n, required this.r, required this.p});
21 |
22 | PieceBuilder get(String notation) {
23 | switch (notation) {
24 | case 'K':
25 | return K;
26 | case 'Q':
27 | return Q;
28 | case 'B':
29 | return B;
30 | case 'N':
31 | return N;
32 | case 'R':
33 | return R;
34 | case 'P':
35 | return P;
36 | case 'k':
37 | return k;
38 | case 'q':
39 | return q;
40 | case 'b':
41 | return b;
42 | case 'n':
43 | return n;
44 | case 'r':
45 | return r;
46 | case 'p':
47 | return p;
48 | default:
49 | throw Exception("Invalid piece notation: '" + notation + "'.");
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/lib/models/square.dart:
--------------------------------------------------------------------------------
1 | class SquareLocation {
2 | final int rank;
3 | final int file;
4 |
5 | SquareLocation(this.rank, this.file);
6 |
7 | SquareLocation.fromString(String square) :
8 | rank = square.codeUnitAt(1) - "1".codeUnitAt(0) + 1,
9 | file = square.codeUnitAt(0) - "a".codeUnitAt(0) + 1;
10 |
11 | int get rankIndex {
12 | return rank - 1;
13 | }
14 |
15 | int get fileIndex {
16 | return file - 1;
17 | }
18 | }
--------------------------------------------------------------------------------
/lib/models/square_info.dart:
--------------------------------------------------------------------------------
1 | class SquareInfo {
2 | final int index;
3 | final int file;
4 | final int rank;
5 | final double size;
6 |
7 | SquareInfo(this.index, this.size) : file = ((index % 8) + 1), rank = ((index / 8).floor() + 1);
8 |
9 | @override
10 | String toString() {
11 | return String.fromCharCode("a".codeUnitAt(0) + (file - 1)) + rank.toString();
12 | }
13 | }
--------------------------------------------------------------------------------
/lib/wp_chessboard.dart:
--------------------------------------------------------------------------------
1 | library wp_chessboard;
2 |
3 | export 'package:wp_chessboard/models/piece_map.dart';
4 | export 'package:wp_chessboard/models/arrow_list.dart';
5 | export 'package:wp_chessboard/models/arrow.dart';
6 | export 'package:wp_chessboard/models/square_info.dart';
7 | export 'package:wp_chessboard/models/piece_drop_event.dart';
8 | export 'package:wp_chessboard/models/board_orientation.dart';
9 | export 'package:wp_chessboard/models/hint_map.dart';
10 | export 'package:wp_chessboard/models/hint_map.dart';
11 | export 'package:wp_chessboard/models/drop_indicator_args.dart';
12 | export 'package:wp_chessboard/models/square.dart';
13 | export 'package:wp_chessboard/components/hints/move_hint.dart';
14 |
15 | import 'package:flutter/material.dart';
16 | import 'package:wp_chessboard/components/arrows.dart';
17 | import 'package:wp_chessboard/components/drop_targets.dart';
18 | import 'package:wp_chessboard/components/hints.dart';
19 | import 'package:wp_chessboard/components/pieces.dart';
20 | import 'package:wp_chessboard/components/squares.dart';
21 | import 'package:wp_chessboard/models/arrow.dart';
22 | import 'package:wp_chessboard/models/arrow_list.dart';
23 | import 'package:wp_chessboard/models/board_orientation.dart';
24 | import 'package:wp_chessboard/models/chess_state.dart';
25 | import 'package:wp_chessboard/models/drop_indicator_args.dart';
26 | import 'package:wp_chessboard/models/hint_map.dart';
27 | import 'package:wp_chessboard/models/piece_drop_event.dart';
28 | import 'package:wp_chessboard/models/piece_map.dart';
29 | import 'package:wp_chessboard/models/square_info.dart';
30 |
31 | class WPChessboard extends StatefulWidget {
32 | final double size;
33 | final Widget Function(SquareInfo) squareBuilder;
34 | final PieceMap pieceMap;
35 | final BoardOrientation orientation;
36 | final WPChessboardController controller;
37 | final void Function(SquareInfo square, String piece)? onPieceTap;
38 | final void Function(SquareInfo square, String piece)? onPieceStartDrag;
39 | final void Function(SquareInfo square)? onEmptyFieldTap;
40 | final void Function(PieceDropEvent)? onPieceDrop;
41 | final bool ghostOnDrag;
42 | final bool turnTopPlayerPieces;
43 | final DropIndicatorArgs? dropIndicator;
44 |
45 |
46 | const WPChessboard({Key? key, required this.size, required this.squareBuilder, required this.pieceMap, required this.controller, this.onPieceTap, this.onPieceDrop, this.onEmptyFieldTap, this.onPieceStartDrag, this.orientation = BoardOrientation.white, this.ghostOnDrag = false, this.dropIndicator, this.turnTopPlayerPieces = false}) : super(key: key);
47 |
48 | @override
49 | State createState() => _WPChessboardState();
50 | }
51 |
52 | class _WPChessboardState extends State {
53 | ChessState state = ChessState("");
54 | HintMap hints = HintMap();
55 | ArrowList arrows = ArrowList([]);
56 |
57 | @override
58 | void initState() {
59 | state = widget.controller.state;
60 | widget.controller.addListener(_controllerListener);
61 | super.initState();
62 | }
63 |
64 | @override
65 | void dispose() {
66 | super.dispose();
67 | widget.controller.removeListener(_controllerListener);
68 | }
69 |
70 | void _controllerListener() {
71 | if (state.fen != widget.controller.state.fen) {
72 | onUpdateState(widget.controller.state);
73 | }
74 | if (hints.id != widget.controller.hints.id) {
75 | onUpdateHints(widget.controller.hints);
76 | }
77 | if (arrows.id != widget.controller.arrows.id) {
78 | onUpdateArrows(widget.controller.arrows);
79 | }
80 | }
81 |
82 | void onUpdateState(ChessState newState) {
83 | setState(() {
84 | state = newState;
85 | });
86 | }
87 |
88 | void onUpdateHints(HintMap newHints) {
89 | setState(() {
90 | hints = newHints;
91 | });
92 | }
93 |
94 | void onUpdateArrows(ArrowList newArrows) {
95 | setState(() {
96 | arrows = newArrows;
97 | });
98 | }
99 |
100 | @override
101 | Widget build(BuildContext context) {
102 | return Container(
103 | color: Colors.black,
104 | width: widget.size,
105 | height: widget.size,
106 | child: RotatedBox(
107 | quarterTurns: (widget.orientation == BoardOrientation.black) ? 2 : 0,
108 | child: Stack(
109 | children: [
110 | Squares(
111 | key: Key("squares_" + widget.size.toString() + "_" + state.fen),
112 | size: widget.size,
113 | squareBuilder: widget.squareBuilder,
114 | ),
115 |
116 | Positioned.fill(
117 | child: Pieces(
118 | key: Key("pieces_" + widget.size.toString() + "_" + state.fen),
119 | size: widget.size,
120 | orientation: widget.orientation,
121 | turnTopPlayerPieces: widget.turnTopPlayerPieces,
122 | pieceMap: widget.pieceMap,
123 | state: state,
124 | onPieceTap: widget.onPieceTap,
125 | onPieceStartDrag: widget.onPieceStartDrag,
126 | disableDrag: widget.onPieceDrop == null,
127 | ghostOnDrag: widget.ghostOnDrag,
128 | onEmptyFieldTap: widget.onEmptyFieldTap,
129 | animated: widget.controller.shouldAnimate
130 | ),
131 | ),
132 |
133 | Positioned.fill(
134 | child: Hints(
135 | key: Key(hints.id.toString()),
136 | size: widget.size,
137 | hints: hints,
138 | ),
139 | ),
140 |
141 | Positioned.fill(
142 | child: Arrows(
143 | size: widget.size,
144 | arrows: arrows.value,
145 | ),
146 | ),
147 |
148 | Positioned.fill(
149 | child: DropTargets(
150 | size: widget.size,
151 | onPieceDrop: widget.onPieceDrop,
152 | dropIndicator: widget.dropIndicator,
153 | ),
154 | ),
155 | ],
156 | ),
157 | )
158 | );
159 | }
160 | }
161 |
162 | class WPChessboardController extends ChangeNotifier {
163 | ChessState state = ChessState("");
164 | HintMap hints = HintMap();
165 | ArrowList arrows = ArrowList([]);
166 | bool shouldAnimate = true;
167 |
168 | WPChessboardController({ initialFen = "" }) {
169 | state = ChessState(initialFen);
170 | }
171 |
172 | void setFen(String value, { bool resetHints = true, bool newGame = false, bool animation = true }) {
173 | shouldAnimate = animation;
174 |
175 | if (newGame) {
176 | state = ChessState(value, last: null);
177 | } else {
178 | state = ChessState(value, last: state);
179 | }
180 |
181 | if (resetHints) {
182 | hints = HintMap();
183 | }
184 |
185 | notifyListeners();
186 | }
187 |
188 | void setHints(HintMap value) {
189 | hints = value;
190 | notifyListeners();
191 | }
192 |
193 | void setArrows(List value) {
194 | arrows = ArrowList(value);
195 | notifyListeners();
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: wp_chessboard
2 | description: A very customizable Chessboard with awesomeness already onboard.
3 | version: 0.0.4
4 | repository: https://github.com/mono424/wp_chessboard
5 |
6 | environment:
7 | sdk: ">=2.16.1 <3.0.0"
8 | flutter: ">=1.17.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 |
14 | dev_dependencies:
15 | flutter_test:
16 | sdk: flutter
17 | flutter_lints: ^1.0.0
18 |
19 | # For information on the generic Dart part of this file, see the
20 | # following page: https://dart.dev/tools/pub/pubspec
21 |
22 | # The following section is specific to Flutter.
23 | flutter:
24 |
25 | # To add assets to your package, add an assets section, like this:
26 | # assets:
27 | # - images/a_dot_burr.jpeg
28 | # - images/a_dot_ham.jpeg
29 | #
30 | # For details regarding assets in packages, see
31 | # https://flutter.dev/assets-and-images/#from-packages
32 | #
33 | # An image asset can refer to one or more resolution-specific "variants", see
34 | # https://flutter.dev/assets-and-images/#resolution-aware.
35 |
36 | # To add custom fonts to your package, add a fonts section here,
37 | # in this "flutter" section. Each entry in this list should have a
38 | # "family" key with the font family name, and a "fonts" key with a
39 | # list giving the asset and other descriptors for the font. For
40 | # example:
41 | # fonts:
42 | # - family: Schyler
43 | # fonts:
44 | # - asset: fonts/Schyler-Regular.ttf
45 | # - asset: fonts/Schyler-Italic.ttf
46 | # style: italic
47 | # - family: Trajan Pro
48 | # fonts:
49 | # - asset: fonts/TrajanPro.ttf
50 | # - asset: fonts/TrajanPro_Bold.ttf
51 | # weight: 700
52 | #
53 | # For details regarding fonts in packages, see
54 | # https://flutter.dev/custom-fonts/#from-packages
55 |
--------------------------------------------------------------------------------
/react_example/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # testing
9 | coverage
10 |
11 | # production
12 | build
13 | public/flutter
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
--------------------------------------------------------------------------------
/react_example/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/react_example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react_example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "react": "^18.2.0",
10 | "react-dom": "^18.2.0",
11 | "react-scripts": "5.0.1",
12 | "web-vitals": "^2.1.4"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": [
22 | "react-app",
23 | "react-app/jest"
24 | ]
25 | },
26 | "browserslist": {
27 | "production": [
28 | ">0.2%",
29 | "not dead",
30 | "not op_mini all"
31 | ],
32 | "development": [
33 | "last 1 chrome version",
34 | "last 1 firefox version",
35 | "last 1 safari version"
36 | ]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react_example/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 | React App
17 |
18 |
19 |
20 |
21 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/react_example/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import WPChessboard from './wp_chessboard/wp_chessboard';
3 |
4 | const sampleGame = [
5 | "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
6 | "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 1",
7 | "rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 1",
8 | "rnbqkbnr/ppp1pppp/8/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq - 0 1",
9 | "rnb1kbnr/ppp1pppp/8/3q4/8/8/PPPP1PPP/RNBQKBNR w KQkq - 0 1",
10 | "rnb1kbnr/ppp1pppp/8/3q4/8/2N5/PPPP1PPP/R1BQKBNR w KQkq - 0 1",
11 | "rnb1kbnr/ppp1pppp/8/q7/8/2N5/PPPP1PPP/R1BQKBNR w KQkq - 0 1",
12 | "rnb1kbnr/ppp1pppp/8/q7/3P4/2N5/PPP2PPP/R1BQKBNR w KQkq - 0 1",
13 | "rnb1kbnr/pp2pppp/2p5/q7/3P4/2N5/PPP2PPP/R1BQKBNR w KQkq - 0 1",
14 | ];
15 |
16 | function App() {
17 | const [currentFen, setCurrentFen] = useState(sampleGame[0]);
18 |
19 | const didLoad = () => {
20 | console.log('WPChessboard loaded');
21 | }
22 |
23 | const play = async () => {
24 | for (const fen of sampleGame) {
25 | setCurrentFen(fen);
26 | await new Promise((resolve) => setTimeout(resolve, 1000));
27 | }
28 | }
29 |
30 | return (
31 |
32 |
39 |
40 |
41 | );
42 | }
43 |
44 | export default App;
45 |
--------------------------------------------------------------------------------
/react_example/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react_example/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 |
6 | const root = ReactDOM.createRoot(document.getElementById('root'));
7 | root.render(
8 |
9 |
10 |
11 | );
12 |
--------------------------------------------------------------------------------
/react_example/src/wp_chessboard/wp_chessboard.jsx:
--------------------------------------------------------------------------------
1 | /* global _flutter */
2 |
3 | import React, { useRef, useEffect, useState } from 'react';
4 |
5 | function WPChessboard({ src, assetBase, didLoad, size, fen }) {
6 | const ref = useRef(null);
7 | const [state, setState] = useState(null);
8 |
9 | useEffect(() => {
10 | if (!ref.current || state) return;
11 | _flutter.loader.loadEntrypoint({
12 | entrypointUrl: src,
13 | onEntrypointLoaded: async (engineInitializer) => {
14 | console.log(ref.current);
15 | let appRunner = await engineInitializer.initializeEngine({
16 | hostElement: ref.current,
17 | assetBase: assetBase,
18 | });
19 | await appRunner.runApp();
20 | }
21 | });
22 |
23 | ref.current.addEventListener("flutter-initialized", (event) => {
24 | let state = event.detail;
25 | didLoad();
26 | setState(state);
27 | }, {
28 | once: true,
29 | });
30 | }, [src, assetBase, didLoad, state]);
31 |
32 | useEffect(() => {
33 | if (!state) return;
34 | state.setSize(size);
35 | }, [size, state]);
36 |
37 | useEffect(() => {
38 | if (!state) return;
39 | state.setFen(fen);
40 | }, [fen, state]);
41 |
42 |
43 | return (
44 |
45 | );
46 | }
47 |
48 | export default WPChessboard;
49 |
--------------------------------------------------------------------------------
/web_example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .packages
31 | .pub-cache/
32 | .pub/
33 | /build/
34 |
35 | # Symbolication related
36 | app.*.symbols
37 |
38 | # Obfuscation related
39 | app.*.map.json
40 |
41 | # Android Studio will place build artifacts here
42 | /android/app/debug
43 | /android/app/profile
44 | /android/app/release
45 |
--------------------------------------------------------------------------------
/web_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.
5 |
6 | version:
7 | revision: 099b3f4bf1581796fac3848d3381dbf2f29edbea
8 | channel: beta
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 099b3f4bf1581796fac3848d3381dbf2f29edbea
17 | base_revision: 099b3f4bf1581796fac3848d3381dbf2f29edbea
18 |
19 | # User provided section
20 |
21 | # List of Local paths (relative to this file) that should be
22 | # ignored by the migrate tool.
23 | #
24 | # Files that are not part of the templates will be ignored by default.
25 | unmanaged_files:
26 | - 'lib/main.dart'
27 | - 'ios/Runner.xcodeproj/project.pbxproj'
28 |
--------------------------------------------------------------------------------
/web_example/README.md:
--------------------------------------------------------------------------------
1 | # web_example
2 |
3 | A new Flutter project.
4 |
--------------------------------------------------------------------------------
/web_example/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
--------------------------------------------------------------------------------
/web_example/build.sh:
--------------------------------------------------------------------------------
1 | flutter build web
2 | rm -rf ../react_example/public/flutter
3 | mkdir ../react_example/public/flutter
4 | cp -r build/web/* ../react_example/public/flutter
--------------------------------------------------------------------------------
/web_example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:chess_vectors_flutter/chess_vectors_flutter.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:wp_chessboard/wp_chessboard.dart';
4 | import 'src/js_interop.dart';
5 |
6 | void main() {
7 | runApp(const MyApp());
8 | }
9 |
10 | extension HexColor on Color {
11 | static Color fromHex(String hexString) {
12 | final buffer = StringBuffer();
13 | if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
14 | buffer.write(hexString.replaceFirst('#', ''));
15 | return Color(int.parse(buffer.toString(), radix: 16));
16 | }
17 |
18 | String toHex({bool leadingHashSign = true}) => '${leadingHashSign ? '#' : ''}'
19 | '${alpha.toRadixString(16).padLeft(2, '0')}'
20 | '${red.toRadixString(16).padLeft(2, '0')}'
21 | '${green.toRadixString(16).padLeft(2, '0')}'
22 | '${blue.toRadixString(16).padLeft(2, '0')}';
23 | }
24 |
25 | Widget Function(SquareInfo) createSquareBuilder(Color light, Color dark) {
26 | return (SquareInfo info) {
27 | Color fieldColor = (info.index + info.rank) % 2 == 0 ? light : dark;
28 | Color overlayColor = Colors.transparent;
29 |
30 | // if (lastMove != null ) {
31 | // if (lastMove!.first.first == info.rank && lastMove!.first.last == info.file) {
32 | // overlayColor = Colors.blueAccent.shade400.withOpacity(0.4);
33 | // } else if (lastMove!.last.first == info.rank && lastMove!.last.last == info.file) {
34 | // overlayColor = Colors.blueAccent.shade400.withOpacity(0.87);
35 | // }
36 | // }
37 |
38 | return Container(
39 | color: fieldColor,
40 | width: info.size,
41 | height: info.size,
42 | child: AnimatedContainer(
43 | color: overlayColor,
44 | width: info.size,
45 | height: info.size,
46 | duration: const Duration(milliseconds: 200),
47 | )
48 | );
49 | };
50 | }
51 |
52 | class MyApp extends StatefulWidget {
53 |
54 | const MyApp({Key? key}) : super(key: key);
55 |
56 | @override
57 | State createState() => _MyAppState();
58 | }
59 |
60 | class _MyAppState extends State {
61 | late final StateManager _state;
62 | final ValueNotifier _fen = ValueNotifier('');
63 | final ValueNotifier _lightColor = ValueNotifier(Colors.grey.shade200.toHex());
64 | final ValueNotifier _darkColor = ValueNotifier(Colors.grey.shade600.toHex());
65 | final ValueNotifier _size= ValueNotifier(400);
66 | final ValueNotifier _orientation= ValueNotifier(false);
67 | final controller = WPChessboardController();
68 |
69 | @override
70 | void initState() {
71 | super.initState();
72 | _state = StateManager(
73 | fen: _fen,
74 | size: _size,
75 | lightColor: _lightColor,
76 | darkColor: _darkColor,
77 | orientation: _orientation,
78 | );
79 | final export = createDartExport(_state);
80 | broadcastAppEvent('flutter-initialized', export);
81 | listenToState();
82 | }
83 |
84 | void listenToState() {
85 | _fen.addListener(() {
86 | update(_fen.value);
87 | });
88 | }
89 |
90 | void onPieceStartDrag(SquareInfo square, String piece) {
91 |
92 | }
93 |
94 | void onPieceTap(SquareInfo square, String piece) {
95 |
96 | }
97 |
98 | void showHintFields(SquareInfo square, String piece) {
99 |
100 | }
101 |
102 | void onEmptyFieldTap(SquareInfo square) {
103 |
104 | }
105 |
106 | void onPieceDrop(PieceDropEvent event) {
107 |
108 | }
109 |
110 | void update(String fen, {bool animated = true}) {
111 | controller.setFen(fen, animation: animated);
112 | }
113 |
114 | void addArrows() {
115 | controller.setArrows([
116 | Arrow(
117 | from: SquareLocation.fromString("b1"),
118 | to: SquareLocation.fromString("c3"),
119 | ),
120 | Arrow(
121 | from: SquareLocation.fromString("g1"),
122 | to: SquareLocation.fromString("f3"),
123 | color: Colors.red
124 | )
125 | ]);
126 | }
127 |
128 | void removeArrows() {
129 | controller.setArrows([]);
130 | }
131 |
132 | BoardOrientation orienatation = BoardOrientation.white;
133 | void toggleArrows() {
134 | setState(() {
135 | if (orienatation == BoardOrientation.white) {
136 | orienatation = BoardOrientation.black;
137 | } else {
138 | orienatation = BoardOrientation.white;
139 | }
140 | });
141 | }
142 |
143 | @override
144 | Widget build(BuildContext context) {
145 | return MaterialApp(
146 | builder: (context, child) => AnimatedBuilder(
147 | animation: Listenable.merge([_size, _lightColor, _darkColor, _orientation]),
148 | builder: (context, _) => WPChessboard(
149 | size: _size.value,
150 | orientation: _orientation.value ? BoardOrientation.black : BoardOrientation.white,
151 | squareBuilder: createSquareBuilder(
152 | HexColor.fromHex(_lightColor.value),
153 | HexColor.fromHex(_darkColor.value)
154 | ),
155 | controller: controller,
156 | // Dont pass any onPieceDrop handler to disable drag and drop
157 | // onPieceDrop: onPieceDrop,
158 | // onPieceTap: onPieceTap,
159 | // onPieceStartDrag: onPieceStartDrag,
160 | // onEmptyFieldTap: onEmptyFieldTap,
161 | turnTopPlayerPieces: false,
162 | ghostOnDrag: true,
163 | // dropIndicator: DropIndicatorArgs(
164 | // size: value / 2,
165 | // color: Colors.lightBlue.withOpacity(0.24)
166 | // ),
167 | pieceMap: PieceMap(
168 | K: (size) => WhiteKing(size: size),
169 | Q: (size) => WhiteQueen(size: size),
170 | B: (size) => WhiteBishop(size: size),
171 | N: (size) => WhiteKnight(size: size),
172 | R: (size) => WhiteRook(size: size),
173 | P: (size) => WhitePawn(size: size),
174 | k: (size) => BlackKing(size: size),
175 | q: (size) => BlackQueen(size: size),
176 | b: (size) => BlackBishop(size: size),
177 | n: (size) => BlackKnight(size: size),
178 | r: (size) => BlackRook(size: size),
179 | p: (size) => BlackPawn(size: size),
180 | ),
181 | ),
182 | ),
183 | );
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/web_example/lib/src/js_interop.dart:
--------------------------------------------------------------------------------
1 | library js_interop;
2 |
3 | export 'js_interop/state_manager.dart';
4 | export 'js_interop/helper.dart' show broadcastAppEvent;
5 | export 'package:js/js_util.dart' show createDartExport;
--------------------------------------------------------------------------------
/web_example/lib/src/js_interop/dom.dart:
--------------------------------------------------------------------------------
1 | import 'dart:js_interop';
2 | import 'package:js/js.dart';
3 | import 'package:js/js_util.dart' as js_util;
4 |
5 | /// Source: https://github.com/flutter/samples/tree/main/web_embedding/ng-flutter/flutter/lib/src/js_interop/dom.dart
6 |
7 | /// This is a little bit of JS-interop code so this Flutter app can dispatch
8 | /// a custom JS event (to be deprecated by package:web)
9 |
10 | @JS('CustomEvent')
11 | @staticInterop
12 | class DomCustomEvent {
13 | external factory DomCustomEvent.withType(JSString type);
14 | external factory DomCustomEvent.withOptions(JSString type, JSAny options);
15 | factory DomCustomEvent._(String type, [Object? options]) {
16 | if (options != null) {
17 | return DomCustomEvent.withOptions(
18 | type.toJS, js_util.jsify(options) as JSAny);
19 | }
20 | return DomCustomEvent.withType(type.toJS);
21 | }
22 | }
23 |
24 | dispatchCustomEvent(DomElement target, String type, Object data) {
25 | final DomCustomEvent event = DomCustomEvent._(type, {
26 | 'bubbles': true,
27 | 'composed': true,
28 | 'detail': data,
29 | });
30 |
31 | target.dispatchEvent(event);
32 | }
33 |
34 | @JS()
35 | @staticInterop
36 | class DomEventTarget {}
37 |
38 | extension DomEventTargetExtension on DomEventTarget {
39 | @JS('dispatchEvent')
40 | external JSBoolean _dispatchEvent(DomCustomEvent event);
41 | bool dispatchEvent(DomCustomEvent event) => _dispatchEvent(event).toDart;
42 | }
43 |
44 | @JS()
45 | @staticInterop
46 | class DomElement extends DomEventTarget {}
47 |
48 | extension DomElementExtension on DomElement {
49 | @JS('querySelector')
50 | external DomElement? _querySelector(JSString selectors);
51 | DomElement? querySelector(String selectors) => _querySelector(selectors.toJS);
52 | }
53 |
54 | @JS()
55 | @staticInterop
56 | class DomDocument extends DomElement {}
57 |
58 | @JS()
59 | @staticInterop
60 | external DomDocument get document;
--------------------------------------------------------------------------------
/web_example/lib/src/js_interop/helper.dart:
--------------------------------------------------------------------------------
1 | import 'dom.dart' as dom;
2 |
3 | /// Source: https://github.com/flutter/samples/tree/main/web_embedding/ng-flutter/flutter/lib/src/js_interop/helper.dart
4 |
5 | /// Locates the root of the flutter app (for now, the first element that has
6 | /// a flt-renderer tag), and dispatches a JS event named [name] with [data].
7 | void broadcastAppEvent(String name, Object data) {
8 | final dom.DomElement? root = dom.document.querySelector('[flt-renderer]');
9 | assert(root != null, 'Flutter root element cannot be found!');
10 |
11 | dom.dispatchCustomEvent(root!, name, data);
12 | }
--------------------------------------------------------------------------------
/web_example/lib/src/js_interop/state_manager.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:js/js.dart';
3 |
4 | @JSExport()
5 | class StateManager {
6 | StateManager({
7 | required ValueNotifier fen,
8 | required ValueNotifier size,
9 | required ValueNotifier lightColor,
10 | required ValueNotifier darkColor,
11 | required ValueNotifier orientation,
12 | }) : _fen = fen, _size = size, _lightColor = lightColor, _darkColor = darkColor, _orientation = orientation;
13 |
14 | final ValueNotifier _fen;
15 | final ValueNotifier _size;
16 | final ValueNotifier _lightColor;
17 | final ValueNotifier _darkColor;
18 | final ValueNotifier _orientation;
19 |
20 | String getFen() {
21 | return _fen.value;
22 | }
23 |
24 | void setFen(String value) {
25 | _fen.value = value;
26 | }
27 |
28 | bool getOrientation() {
29 | return _orientation.value;
30 | }
31 |
32 | void setOrientation(bool value) {
33 | _orientation.value = value;
34 | }
35 |
36 | double getSize() {
37 | return _size.value;
38 | }
39 |
40 | void setSize(double value) {
41 | _size.value = value;
42 | }
43 |
44 | String getLightColor() {
45 | return _lightColor.value;
46 | }
47 |
48 | void setLightColor(String value) {
49 | _lightColor.value = value;
50 | }
51 |
52 | String getDarkColor() {
53 | return _darkColor.value;
54 | }
55 |
56 | void setDarkColor(String value) {
57 | _darkColor.value = value;
58 | }
59 |
60 | void onFenChanged(VoidCallback f) {
61 | _fen.addListener(f);
62 | }
63 | }
--------------------------------------------------------------------------------
/web_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 | chess_vectors_flutter:
29 | dependency: "direct main"
30 | description:
31 | name: chess_vectors_flutter
32 | sha256: "988ff9ec3fa00174f0c0bbe0d50ca776803d9c8fff84d326876ee8a2e11dce31"
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.0.18"
36 | clock:
37 | dependency: transitive
38 | description:
39 | name: clock
40 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.1.1"
44 | collection:
45 | dependency: transitive
46 | description:
47 | name: collection
48 | sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.17.1"
52 | fake_async:
53 | dependency: transitive
54 | description:
55 | name: fake_async
56 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "1.3.1"
60 | flutter:
61 | dependency: "direct main"
62 | description: flutter
63 | source: sdk
64 | version: "0.0.0"
65 | flutter_lints:
66 | dependency: "direct dev"
67 | description:
68 | name: flutter_lints
69 | sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
70 | url: "https://pub.dev"
71 | source: hosted
72 | version: "2.0.1"
73 | flutter_test:
74 | dependency: "direct dev"
75 | description: flutter
76 | source: sdk
77 | version: "0.0.0"
78 | js:
79 | dependency: "direct main"
80 | description:
81 | name: js
82 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
83 | url: "https://pub.dev"
84 | source: hosted
85 | version: "0.6.7"
86 | lints:
87 | dependency: transitive
88 | description:
89 | name: lints
90 | sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
91 | url: "https://pub.dev"
92 | source: hosted
93 | version: "2.0.1"
94 | matcher:
95 | dependency: transitive
96 | description:
97 | name: matcher
98 | sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
99 | url: "https://pub.dev"
100 | source: hosted
101 | version: "0.12.15"
102 | material_color_utilities:
103 | dependency: transitive
104 | description:
105 | name: material_color_utilities
106 | sha256: "586678f20e112219ed0f73215f01bcdf1d769824ba2ebae45ad918a9bfde9bdb"
107 | url: "https://pub.dev"
108 | source: hosted
109 | version: "0.3.0"
110 | meta:
111 | dependency: transitive
112 | description:
113 | name: meta
114 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
115 | url: "https://pub.dev"
116 | source: hosted
117 | version: "1.9.1"
118 | path:
119 | dependency: transitive
120 | description:
121 | name: path
122 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
123 | url: "https://pub.dev"
124 | source: hosted
125 | version: "1.8.3"
126 | sky_engine:
127 | dependency: transitive
128 | description: flutter
129 | source: sdk
130 | version: "0.0.99"
131 | source_span:
132 | dependency: transitive
133 | description:
134 | name: source_span
135 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
136 | url: "https://pub.dev"
137 | source: hosted
138 | version: "1.10.0"
139 | stack_trace:
140 | dependency: transitive
141 | description:
142 | name: stack_trace
143 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
144 | url: "https://pub.dev"
145 | source: hosted
146 | version: "1.11.0"
147 | stream_channel:
148 | dependency: transitive
149 | description:
150 | name: stream_channel
151 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
152 | url: "https://pub.dev"
153 | source: hosted
154 | version: "2.1.1"
155 | string_scanner:
156 | dependency: transitive
157 | description:
158 | name: string_scanner
159 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
160 | url: "https://pub.dev"
161 | source: hosted
162 | version: "1.2.0"
163 | term_glyph:
164 | dependency: transitive
165 | description:
166 | name: term_glyph
167 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
168 | url: "https://pub.dev"
169 | source: hosted
170 | version: "1.2.1"
171 | test_api:
172 | dependency: transitive
173 | description:
174 | name: test_api
175 | sha256: daadc9baabec998b062c9091525aa95786508b1c48e9c30f1f891b8bf6ff2e64
176 | url: "https://pub.dev"
177 | source: hosted
178 | version: "0.5.2"
179 | tuple:
180 | dependency: transitive
181 | description:
182 | name: tuple
183 | sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa"
184 | url: "https://pub.dev"
185 | source: hosted
186 | version: "2.0.1"
187 | vector_math:
188 | dependency: transitive
189 | description:
190 | name: vector_math
191 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
192 | url: "https://pub.dev"
193 | source: hosted
194 | version: "2.1.4"
195 | wp_chessboard:
196 | dependency: "direct main"
197 | description:
198 | path: ".."
199 | relative: true
200 | source: path
201 | version: "0.0.3"
202 | sdks:
203 | dart: ">=3.0.0-0 <4.0.0"
204 | flutter: ">=1.17.0"
205 |
--------------------------------------------------------------------------------
/web_example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: web_example
2 | description: A new Flutter project.
3 | publish_to: 'none'
4 | version: 0.1.0
5 |
6 | environment:
7 | sdk: '>=2.19.0-444.6.beta <3.0.0'
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | wp_chessboard:
13 | path: "../"
14 | js: ^0.6.7
15 | chess_vectors_flutter: ^1.0.18
16 |
17 | dev_dependencies:
18 | flutter_test:
19 | sdk: flutter
20 | flutter_lints: ^2.0.0
21 |
22 | flutter:
23 | uses-material-design: true
24 |
--------------------------------------------------------------------------------
/web_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 in the flutter_test package. 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:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:web_example/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/web_example/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mono424/wp_chessboard/07597ca81d647d5a07dfb550daa96707977afc64/web_example/web/favicon.png
--------------------------------------------------------------------------------
/web_example/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | wp_chessboard
27 |
28 |
32 |
33 |
34 |
35 |
36 |
58 |
59 |
--------------------------------------------------------------------------------