├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── arrow_path.iml
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── tengio
│ │ │ │ │ └── example
│ │ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ │ ├── 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
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── arrow_path_example.png
├── ios
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── Runner
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── 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
│ │ └── main.m
├── lib
│ └── main.dart
├── pubspec.lock
└── pubspec.yaml
├── lib
└── arrow_path.dart
├── pubspec.lock
└── pubspec.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 | ios/.generated/
9 | ios/Flutter/Generated.xcconfig
10 | ios/Runner/GeneratedPluginRegistrant.*
11 | .idea
12 | example/ios/Flutter/flutter_export_environment.sh
13 |
--------------------------------------------------------------------------------
/.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: 8661d8aecd626f7f57ccbcb735553edc05a2e713
8 | channel: stable
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [3.1.0] - 2023-06-02
2 |
3 | * *DEPRECATED* Deprecated ArrowPath.make(), use ArrowPath.addTip() instead.
4 | * Added ArrowPath.addTip(), which is the same as ArrowPath.make() but without `isDoubleSided` and with the new `isBackward` argument.
5 | This will allow more control on what side the arrow should be added.
6 | * Updated README to add migration instructions.
7 | * Updated for Flutter 3.10 and Dart 3.
8 | * Update Example app.
9 | * Update License wording (same license).
10 |
11 | ## [3.0.0] - 2022-07-18
12 |
13 | * *(Potentially) Breaking change:* Updated to AndroidX.
14 | * Fixed issue when the given path is too small (for example a 0 length path). Thanks to @Freancy for bug report.
15 | * Example App: Added ScrollView and removed vertical screen constraint.
16 | * Example App: Update to Android embedding V2.
17 | * Improved code style.
18 |
19 | ## [2.0.0] - 2021-04-29
20 |
21 | * *Breaking change:* Null safety
22 |
23 | ## [1.0.0] - 2019-05-11
24 |
25 | * Initial release.
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Quentin Le Guennec
2 |
3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4 |
5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6 |
7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 |
9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10 |
11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [](https://pub.dev/packages/arrow_path)
3 | [](https://pub.dev/packages/arrow_path/score)
4 |
5 |
6 | # Flutter arrow_path package
7 |
8 | Draw arrows with Path objects easily. Paths can be composited to add arrows to any curve and draw all at once.
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | The arrow is drawn using the direction of the tangent to the curve at the end of the curve.
17 | It features an adjustment parameter to also look at the tangent just before the end of the
18 | segment and rotate the tip of the arrow based on the angle difference to improve the look of the arrow
19 | when the curvature at the end is high.
20 |
21 | ## Getting Started
22 |
23 | Have a look at the [example app](https://github.com/quentinleguennec/flutter-arrow-path/blob/master/example/lib/main.dart) to get started.
24 |
25 | ## Migration from [3.0.0] to [3.1.0]
26 |
27 | ArrowPath.make() is now deprecated, use ArrowPath.addTip() instead.
28 |
29 |
30 | If you are not using the `isDoubleSided` argument of ArrowPath.make() then you can safely replace it by ArrowPath.addTip() without any other change.
31 |
32 |
33 | If you are using the `isDoubleSided` argument of ArrowPath.make() then change yor code like this:
34 |
35 |
36 | Before:
37 | ```dart
38 | Path path = Path();
39 | path.relativeLineTo(100, 100);
40 | path = ArrowPath.make(path, isDoubleSided: true);
41 | ```
42 |
43 | After:
44 | ```dart
45 | Path path = Path();
46 | path.relativeLineTo(100, 100);
47 | path = ArrowPath.addTip(path);
48 | path = ArrowPath.addTip(path, isBackward: true);
49 | ```
--------------------------------------------------------------------------------
/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 | # List of lints:
6 | # https://dart.dev/tools/linter-rules
7 |
8 | analyzer:
9 | exclude: [build/**]
10 | language:
11 | strict-casts: true
12 | strict-inference: true
13 | strict-raw-types: true
14 | plugins:
15 | - dart_code_metrics
16 |
17 | linter:
18 | rules:
19 | always_declare_return_types: true
20 | prefer_single_quotes: true
21 | only_throw_errors: true
22 | cancel_subscriptions: true
23 | close_sinks: true
24 | prefer_final_fields: true
25 | prefer_final_locals: true
26 | prefer_final_in_for_each: true
27 | use_build_context_synchronously: true
28 | await_only_futures: true
29 | unawaited_futures: true
30 | always_specify_types: false
31 | avoid_function_literals_in_foreach_calls: false
32 |
33 | dart_code_metrics:
34 | metrics-exclude:
35 | - test/**
36 | rules:
37 | - prefer-trailing-comma
38 | - no-equal-then-else
39 |
--------------------------------------------------------------------------------
/arrow_path.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/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 | # Visual Studio Code related
19 | .vscode/
20 |
21 | # Flutter/Dart/Pub related
22 | **/doc/api/
23 | .dart_tool/
24 | .flutter-plugins
25 | .packages
26 | .pub-cache/
27 | .pub/
28 | /build/
29 |
30 | # Android related
31 | **/android/**/gradle-wrapper.jar
32 | **/android/.gradle
33 | **/android/captures/
34 | **/android/gradlew
35 | **/android/gradlew.bat
36 | **/android/local.properties
37 | **/android/**/GeneratedPluginRegistrant.java
38 |
39 | # iOS/XCode related
40 | **/ios/**/*.mode1v3
41 | **/ios/**/*.mode2v3
42 | **/ios/**/*.moved-aside
43 | **/ios/**/*.pbxuser
44 | **/ios/**/*.perspectivev3
45 | **/ios/**/*sync/
46 | **/ios/**/.sconsign.dblite
47 | **/ios/**/.tags*
48 | **/ios/**/.vagrant/
49 | **/ios/**/DerivedData/
50 | **/ios/**/Icon?
51 | **/ios/**/Pods/
52 | **/ios/**/.symlinks/
53 | **/ios/**/profile
54 | **/ios/**/xcuserdata
55 | **/ios/.generated/
56 | **/ios/Flutter/App.framework
57 | **/ios/Flutter/Flutter.framework
58 | **/ios/Flutter/Generated.xcconfig
59 | **/ios/Flutter/app.flx
60 | **/ios/Flutter/app.zip
61 | **/ios/Flutter/flutter_assets/
62 | **/ios/ServiceDefinitions.json
63 | **/ios/Runner/GeneratedPluginRegistrant.*
64 |
65 | # Exceptions to above rules.
66 | !**/ios/**/default.mode1v3
67 | !**/ios/**/default.mode2v3
68 | !**/ios/**/default.pbxuser
69 | !**/ios/**/default.perspectivev3
70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
71 |
--------------------------------------------------------------------------------
/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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Example app
2 |
3 | Example project for the arrow_path package.
4 |
--------------------------------------------------------------------------------
/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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26 |
27 | android {
28 | compileSdkVersion flutter.compileSdkVersion
29 |
30 | compileOptions {
31 | sourceCompatibility JavaVersion.VERSION_1_8
32 | targetCompatibility JavaVersion.VERSION_1_8
33 | }
34 |
35 | defaultConfig {
36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
37 | applicationId "com.tengio.example"
38 | minSdkVersion flutter.minSdkVersion
39 | targetSdkVersion flutter.targetSdkVersion
40 | versionCode flutterVersionCode.toInteger()
41 | versionName flutterVersionName
42 | }
43 |
44 | buildTypes {
45 | release {
46 | // TODO: Add your own signing config for the release build.
47 | // Signing with the debug keys for now, so `flutter run --release` works.
48 | signingConfig signingConfigs.debug
49 | }
50 | }
51 | }
52 |
53 | flutter {
54 | source '../..'
55 | }
56 |
57 | dependencies {
58 | }
59 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
16 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/tengio/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.tengio.example;
2 |
3 | import io.flutter.embedding.android.FlutterActivity;
4 |
5 | public class MainActivity extends FlutterActivity {
6 | }
7 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/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 | tasks.register("clean", Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
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-7.6.1-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/example/arrow_path_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/example/arrow_path_example.png
--------------------------------------------------------------------------------
/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 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
13 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
14 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXCopyFilesBuildPhase section */
21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
22 | isa = PBXCopyFilesBuildPhase;
23 | buildActionMask = 2147483647;
24 | dstPath = "";
25 | dstSubfolderSpec = 10;
26 | files = (
27 | );
28 | name = "Embed Frameworks";
29 | runOnlyForDeploymentPostprocessing = 0;
30 | };
31 | /* End PBXCopyFilesBuildPhase section */
32 |
33 | /* Begin PBXFileReference section */
34 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
35 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
36 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
38 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
39 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
40 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
41 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
42 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
44 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
45 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
46 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
47 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
48 | /* End PBXFileReference section */
49 |
50 | /* Begin PBXFrameworksBuildPhase section */
51 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
52 | isa = PBXFrameworksBuildPhase;
53 | buildActionMask = 2147483647;
54 | files = (
55 | );
56 | runOnlyForDeploymentPostprocessing = 0;
57 | };
58 | /* End PBXFrameworksBuildPhase section */
59 |
60 | /* Begin PBXGroup section */
61 | 9740EEB11CF90186004384FC /* Flutter */ = {
62 | isa = PBXGroup;
63 | children = (
64 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
65 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
66 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
67 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
68 | );
69 | name = Flutter;
70 | sourceTree = "";
71 | };
72 | 97C146E51CF9000F007C117D = {
73 | isa = PBXGroup;
74 | children = (
75 | 9740EEB11CF90186004384FC /* Flutter */,
76 | 97C146F01CF9000F007C117D /* Runner */,
77 | 97C146EF1CF9000F007C117D /* Products */,
78 | CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
79 | );
80 | sourceTree = "";
81 | };
82 | 97C146EF1CF9000F007C117D /* Products */ = {
83 | isa = PBXGroup;
84 | children = (
85 | 97C146EE1CF9000F007C117D /* Runner.app */,
86 | );
87 | name = Products;
88 | sourceTree = "";
89 | };
90 | 97C146F01CF9000F007C117D /* Runner */ = {
91 | isa = PBXGroup;
92 | children = (
93 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
94 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
95 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
96 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
97 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
98 | 97C147021CF9000F007C117D /* Info.plist */,
99 | 97C146F11CF9000F007C117D /* Supporting Files */,
100 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
101 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
102 | );
103 | path = Runner;
104 | sourceTree = "";
105 | };
106 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
107 | isa = PBXGroup;
108 | children = (
109 | 97C146F21CF9000F007C117D /* main.m */,
110 | );
111 | name = "Supporting Files";
112 | sourceTree = "";
113 | };
114 | /* End PBXGroup section */
115 |
116 | /* Begin PBXNativeTarget section */
117 | 97C146ED1CF9000F007C117D /* Runner */ = {
118 | isa = PBXNativeTarget;
119 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
120 | buildPhases = (
121 | 9740EEB61CF901F6004384FC /* Run Script */,
122 | 97C146EA1CF9000F007C117D /* Sources */,
123 | 97C146EB1CF9000F007C117D /* Frameworks */,
124 | 97C146EC1CF9000F007C117D /* Resources */,
125 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
126 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
127 | );
128 | buildRules = (
129 | );
130 | dependencies = (
131 | );
132 | name = Runner;
133 | productName = Runner;
134 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
135 | productType = "com.apple.product-type.application";
136 | };
137 | /* End PBXNativeTarget section */
138 |
139 | /* Begin PBXProject section */
140 | 97C146E61CF9000F007C117D /* Project object */ = {
141 | isa = PBXProject;
142 | attributes = {
143 | LastUpgradeCheck = 1300;
144 | ORGANIZATIONNAME = "The Chromium Authors";
145 | TargetAttributes = {
146 | 97C146ED1CF9000F007C117D = {
147 | CreatedOnToolsVersion = 7.3.1;
148 | };
149 | };
150 | };
151 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
152 | compatibilityVersion = "Xcode 3.2";
153 | developmentRegion = English;
154 | hasScannedForEncodings = 0;
155 | knownRegions = (
156 | en,
157 | Base,
158 | );
159 | mainGroup = 97C146E51CF9000F007C117D;
160 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
161 | projectDirPath = "";
162 | projectRoot = "";
163 | targets = (
164 | 97C146ED1CF9000F007C117D /* Runner */,
165 | );
166 | };
167 | /* End PBXProject section */
168 |
169 | /* Begin PBXResourcesBuildPhase section */
170 | 97C146EC1CF9000F007C117D /* Resources */ = {
171 | isa = PBXResourcesBuildPhase;
172 | buildActionMask = 2147483647;
173 | files = (
174 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
175 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
176 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
177 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
178 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
179 | );
180 | runOnlyForDeploymentPostprocessing = 0;
181 | };
182 | /* End PBXResourcesBuildPhase section */
183 |
184 | /* Begin PBXShellScriptBuildPhase section */
185 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
186 | isa = PBXShellScriptBuildPhase;
187 | buildActionMask = 2147483647;
188 | files = (
189 | );
190 | inputPaths = (
191 | );
192 | name = "Thin Binary";
193 | outputPaths = (
194 | );
195 | runOnlyForDeploymentPostprocessing = 0;
196 | shellPath = /bin/sh;
197 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
198 | };
199 | 9740EEB61CF901F6004384FC /* Run Script */ = {
200 | isa = PBXShellScriptBuildPhase;
201 | buildActionMask = 2147483647;
202 | files = (
203 | );
204 | inputPaths = (
205 | );
206 | name = "Run Script";
207 | outputPaths = (
208 | );
209 | runOnlyForDeploymentPostprocessing = 0;
210 | shellPath = /bin/sh;
211 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
212 | };
213 | /* End PBXShellScriptBuildPhase section */
214 |
215 | /* Begin PBXSourcesBuildPhase section */
216 | 97C146EA1CF9000F007C117D /* Sources */ = {
217 | isa = PBXSourcesBuildPhase;
218 | buildActionMask = 2147483647;
219 | files = (
220 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
221 | 97C146F31CF9000F007C117D /* main.m in Sources */,
222 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
223 | );
224 | runOnlyForDeploymentPostprocessing = 0;
225 | };
226 | /* End PBXSourcesBuildPhase section */
227 |
228 | /* Begin PBXVariantGroup section */
229 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
230 | isa = PBXVariantGroup;
231 | children = (
232 | 97C146FB1CF9000F007C117D /* Base */,
233 | );
234 | name = Main.storyboard;
235 | sourceTree = "";
236 | };
237 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
238 | isa = PBXVariantGroup;
239 | children = (
240 | 97C147001CF9000F007C117D /* Base */,
241 | );
242 | name = LaunchScreen.storyboard;
243 | sourceTree = "";
244 | };
245 | /* End PBXVariantGroup section */
246 |
247 | /* Begin XCBuildConfiguration section */
248 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
249 | isa = XCBuildConfiguration;
250 | buildSettings = {
251 | ALWAYS_SEARCH_USER_PATHS = NO;
252 | CLANG_ANALYZER_NONNULL = YES;
253 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
254 | CLANG_CXX_LIBRARY = "libc++";
255 | CLANG_ENABLE_MODULES = YES;
256 | CLANG_ENABLE_OBJC_ARC = YES;
257 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
258 | CLANG_WARN_BOOL_CONVERSION = YES;
259 | CLANG_WARN_COMMA = YES;
260 | CLANG_WARN_CONSTANT_CONVERSION = YES;
261 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
262 | CLANG_WARN_EMPTY_BODY = YES;
263 | CLANG_WARN_ENUM_CONVERSION = YES;
264 | CLANG_WARN_INFINITE_RECURSION = YES;
265 | CLANG_WARN_INT_CONVERSION = YES;
266 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
267 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
268 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
269 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
270 | CLANG_WARN_STRICT_PROTOTYPES = YES;
271 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
272 | CLANG_WARN_UNREACHABLE_CODE = YES;
273 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
274 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
275 | COPY_PHASE_STRIP = NO;
276 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
277 | ENABLE_NS_ASSERTIONS = NO;
278 | ENABLE_STRICT_OBJC_MSGSEND = YES;
279 | GCC_C_LANGUAGE_STANDARD = gnu99;
280 | GCC_NO_COMMON_BLOCKS = YES;
281 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
282 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
283 | GCC_WARN_UNDECLARED_SELECTOR = YES;
284 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
285 | GCC_WARN_UNUSED_FUNCTION = YES;
286 | GCC_WARN_UNUSED_VARIABLE = YES;
287 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
288 | MTL_ENABLE_DEBUG_INFO = NO;
289 | SDKROOT = iphoneos;
290 | TARGETED_DEVICE_FAMILY = "1,2";
291 | VALIDATE_PRODUCT = YES;
292 | };
293 | name = Profile;
294 | };
295 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
296 | isa = XCBuildConfiguration;
297 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
298 | buildSettings = {
299 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
300 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
301 | DEVELOPMENT_TEAM = S8QB4VV633;
302 | ENABLE_BITCODE = NO;
303 | FRAMEWORK_SEARCH_PATHS = (
304 | "$(inherited)",
305 | "$(PROJECT_DIR)/Flutter",
306 | );
307 | INFOPLIST_FILE = Runner/Info.plist;
308 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
309 | LIBRARY_SEARCH_PATHS = (
310 | "$(inherited)",
311 | "$(PROJECT_DIR)/Flutter",
312 | );
313 | PRODUCT_BUNDLE_IDENTIFIER = com.tengio.example;
314 | PRODUCT_NAME = "$(TARGET_NAME)";
315 | VERSIONING_SYSTEM = "apple-generic";
316 | };
317 | name = Profile;
318 | };
319 | 97C147031CF9000F007C117D /* Debug */ = {
320 | isa = XCBuildConfiguration;
321 | buildSettings = {
322 | ALWAYS_SEARCH_USER_PATHS = NO;
323 | CLANG_ANALYZER_NONNULL = YES;
324 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
325 | CLANG_CXX_LIBRARY = "libc++";
326 | CLANG_ENABLE_MODULES = YES;
327 | CLANG_ENABLE_OBJC_ARC = YES;
328 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
329 | CLANG_WARN_BOOL_CONVERSION = YES;
330 | CLANG_WARN_COMMA = YES;
331 | CLANG_WARN_CONSTANT_CONVERSION = YES;
332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
333 | CLANG_WARN_EMPTY_BODY = YES;
334 | CLANG_WARN_ENUM_CONVERSION = YES;
335 | CLANG_WARN_INFINITE_RECURSION = YES;
336 | CLANG_WARN_INT_CONVERSION = YES;
337 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
338 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
339 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
340 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
341 | CLANG_WARN_STRICT_PROTOTYPES = YES;
342 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
343 | CLANG_WARN_UNREACHABLE_CODE = YES;
344 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
345 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
346 | COPY_PHASE_STRIP = NO;
347 | DEBUG_INFORMATION_FORMAT = dwarf;
348 | ENABLE_STRICT_OBJC_MSGSEND = YES;
349 | ENABLE_TESTABILITY = YES;
350 | GCC_C_LANGUAGE_STANDARD = gnu99;
351 | GCC_DYNAMIC_NO_PIC = NO;
352 | GCC_NO_COMMON_BLOCKS = YES;
353 | GCC_OPTIMIZATION_LEVEL = 0;
354 | GCC_PREPROCESSOR_DEFINITIONS = (
355 | "DEBUG=1",
356 | "$(inherited)",
357 | );
358 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
359 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
360 | GCC_WARN_UNDECLARED_SELECTOR = YES;
361 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
362 | GCC_WARN_UNUSED_FUNCTION = YES;
363 | GCC_WARN_UNUSED_VARIABLE = YES;
364 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
365 | MTL_ENABLE_DEBUG_INFO = YES;
366 | ONLY_ACTIVE_ARCH = YES;
367 | SDKROOT = iphoneos;
368 | TARGETED_DEVICE_FAMILY = "1,2";
369 | };
370 | name = Debug;
371 | };
372 | 97C147041CF9000F007C117D /* Release */ = {
373 | isa = XCBuildConfiguration;
374 | buildSettings = {
375 | ALWAYS_SEARCH_USER_PATHS = NO;
376 | CLANG_ANALYZER_NONNULL = YES;
377 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
378 | CLANG_CXX_LIBRARY = "libc++";
379 | CLANG_ENABLE_MODULES = YES;
380 | CLANG_ENABLE_OBJC_ARC = YES;
381 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
382 | CLANG_WARN_BOOL_CONVERSION = YES;
383 | CLANG_WARN_COMMA = YES;
384 | CLANG_WARN_CONSTANT_CONVERSION = YES;
385 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
386 | CLANG_WARN_EMPTY_BODY = YES;
387 | CLANG_WARN_ENUM_CONVERSION = YES;
388 | CLANG_WARN_INFINITE_RECURSION = YES;
389 | CLANG_WARN_INT_CONVERSION = YES;
390 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
391 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
392 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
393 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
394 | CLANG_WARN_STRICT_PROTOTYPES = YES;
395 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
396 | CLANG_WARN_UNREACHABLE_CODE = YES;
397 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
398 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
399 | COPY_PHASE_STRIP = NO;
400 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
401 | ENABLE_NS_ASSERTIONS = NO;
402 | ENABLE_STRICT_OBJC_MSGSEND = YES;
403 | GCC_C_LANGUAGE_STANDARD = gnu99;
404 | GCC_NO_COMMON_BLOCKS = YES;
405 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
406 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
407 | GCC_WARN_UNDECLARED_SELECTOR = YES;
408 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
409 | GCC_WARN_UNUSED_FUNCTION = YES;
410 | GCC_WARN_UNUSED_VARIABLE = YES;
411 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
412 | MTL_ENABLE_DEBUG_INFO = NO;
413 | SDKROOT = iphoneos;
414 | TARGETED_DEVICE_FAMILY = "1,2";
415 | VALIDATE_PRODUCT = YES;
416 | };
417 | name = Release;
418 | };
419 | 97C147061CF9000F007C117D /* Debug */ = {
420 | isa = XCBuildConfiguration;
421 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
422 | buildSettings = {
423 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
424 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
425 | ENABLE_BITCODE = NO;
426 | FRAMEWORK_SEARCH_PATHS = (
427 | "$(inherited)",
428 | "$(PROJECT_DIR)/Flutter",
429 | );
430 | INFOPLIST_FILE = Runner/Info.plist;
431 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
432 | LIBRARY_SEARCH_PATHS = (
433 | "$(inherited)",
434 | "$(PROJECT_DIR)/Flutter",
435 | );
436 | PRODUCT_BUNDLE_IDENTIFIER = com.tengio.example;
437 | PRODUCT_NAME = "$(TARGET_NAME)";
438 | VERSIONING_SYSTEM = "apple-generic";
439 | };
440 | name = Debug;
441 | };
442 | 97C147071CF9000F007C117D /* Release */ = {
443 | isa = XCBuildConfiguration;
444 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
445 | buildSettings = {
446 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
447 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
448 | ENABLE_BITCODE = NO;
449 | FRAMEWORK_SEARCH_PATHS = (
450 | "$(inherited)",
451 | "$(PROJECT_DIR)/Flutter",
452 | );
453 | INFOPLIST_FILE = Runner/Info.plist;
454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
455 | LIBRARY_SEARCH_PATHS = (
456 | "$(inherited)",
457 | "$(PROJECT_DIR)/Flutter",
458 | );
459 | PRODUCT_BUNDLE_IDENTIFIER = com.tengio.example;
460 | PRODUCT_NAME = "$(TARGET_NAME)";
461 | VERSIONING_SYSTEM = "apple-generic";
462 | };
463 | name = Release;
464 | };
465 | /* End XCBuildConfiguration section */
466 |
467 | /* Begin XCConfigurationList section */
468 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
469 | isa = XCConfigurationList;
470 | buildConfigurations = (
471 | 97C147031CF9000F007C117D /* Debug */,
472 | 97C147041CF9000F007C117D /* Release */,
473 | 249021D3217E4FDB00AE95B9 /* Profile */,
474 | );
475 | defaultConfigurationIsVisible = 0;
476 | defaultConfigurationName = Release;
477 | };
478 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
479 | isa = XCConfigurationList;
480 | buildConfigurations = (
481 | 97C147061CF9000F007C117D /* Debug */,
482 | 97C147071CF9000F007C117D /* Release */,
483 | 249021D4217E4FDB00AE95B9 /* Profile */,
484 | );
485 | defaultConfigurationIsVisible = 0;
486 | defaultConfigurationName = Release;
487 | };
488 | /* End XCConfigurationList section */
489 | };
490 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
491 | }
492 |
--------------------------------------------------------------------------------
/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/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/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/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quentinleguennec/flutter-arrow-path/1d37eab5fe676d93ac64f76a8f6fced1a7b0e44c/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 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | example
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 | CADisableMinimumFrameDurationOnPhone
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math' as math;
2 |
3 | import 'package:arrow_path/arrow_path.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | void main() => runApp(const MyApp());
7 |
8 | class MyApp extends StatelessWidget {
9 | const MyApp({Key? key}) : super(key: key);
10 |
11 | @override
12 | Widget build(BuildContext context) => MaterialApp(
13 | title: 'Arrow Path Example',
14 | theme: ThemeData(primarySwatch: Colors.blue),
15 | home: const ExampleApp(),
16 | );
17 | }
18 |
19 | class ExampleApp extends StatelessWidget {
20 | const ExampleApp({Key? key}) : super(key: key);
21 |
22 | @override
23 | Widget build(BuildContext context) => Scaffold(
24 | appBar: AppBar(
25 | title: const Text('Arrow Path Example'),
26 | ),
27 | body: SingleChildScrollView(
28 | child: ClipRect(
29 | child: CustomPaint(
30 | size: Size(MediaQuery.of(context).size.width, 700),
31 | painter: ArrowPainter(),
32 | ),
33 | ),
34 | ),
35 | );
36 | }
37 |
38 | class ArrowPainter extends CustomPainter {
39 | @override
40 | void paint(Canvas canvas, Size size) {
41 | /// The arrows usually looks better with rounded caps.
42 | final Paint paint = Paint()
43 | ..color = Colors.black
44 | ..style = PaintingStyle.stroke
45 | ..strokeCap = StrokeCap.round
46 | ..strokeJoin = StrokeJoin.round
47 | ..strokeWidth = 3.0;
48 |
49 | /// Draw a single arrow.
50 | {
51 | Path path = Path();
52 | path.moveTo(size.width * 0.25, 60);
53 | path.relativeCubicTo(0, 0, size.width * 0.25, 50, size.width * 0.5, 0);
54 | path = ArrowPath.addTip(path);
55 |
56 | canvas.drawPath(path, paint..color = Colors.blue);
57 |
58 | const TextSpan textSpan = TextSpan(
59 | text: 'Single arrow',
60 | style: TextStyle(color: Colors.blue),
61 | );
62 | final TextPainter textPainter = TextPainter(
63 | text: textSpan,
64 | textAlign: TextAlign.center,
65 | textDirection: TextDirection.ltr,
66 | );
67 | textPainter.layout(minWidth: size.width);
68 | textPainter.paint(canvas, const Offset(0, 36));
69 | }
70 |
71 | /// Draw a double sided arrow.
72 | {
73 | Path path = Path();
74 | path.moveTo(size.width * 0.25, 120);
75 | path.relativeCubicTo(0, 0, size.width * 0.25, 50, size.width * 0.5, 0);
76 | path = ArrowPath.addTip(path);
77 | path = ArrowPath.addTip(path, isBackward: true);
78 |
79 | canvas.drawPath(path, paint..color = Colors.cyan);
80 |
81 | const TextSpan textSpan = TextSpan(
82 | text: 'Double sided arrow',
83 | style: TextStyle(color: Colors.cyan),
84 | );
85 | final TextPainter textPainter = TextPainter(
86 | text: textSpan,
87 | textAlign: TextAlign.center,
88 | textDirection: TextDirection.ltr,
89 | );
90 | textPainter.layout(minWidth: size.width);
91 | textPainter.paint(canvas, const Offset(0, 96));
92 | }
93 |
94 | /// Use complex path.
95 | {
96 | Path path = Path();
97 | path.moveTo(size.width * 0.25, 180);
98 | path.relativeCubicTo(0, 0, size.width * 0.25, 50, size.width * 0.5, 50);
99 | path.relativeCubicTo(0, 0, -size.width * 0.25, 0, -size.width * 0.5, 50);
100 | path.relativeCubicTo(0, 0, size.width * 0.125, 10, size.width * 0.25, -10);
101 | path = ArrowPath.addTip(path);
102 | canvas.drawPath(path, paint..color = Colors.blue);
103 |
104 | const TextSpan textSpan = TextSpan(
105 | text: 'Complex path',
106 | style: TextStyle(color: Colors.blue),
107 | );
108 | final TextPainter textPainter = TextPainter(
109 | text: textSpan,
110 | textAlign: TextAlign.center,
111 | textDirection: TextDirection.ltr,
112 | );
113 | textPainter.layout(minWidth: size.width);
114 | textPainter.paint(canvas, const Offset(0, 168));
115 | }
116 |
117 | /// Path with several forward arrow and one backward arrow.
118 | /// IMPORTANT: You should never use more than a single backward arrow on the same path, or the results
119 | /// may be unpredictable due to limitations of the Path API.
120 | ///
121 | /// If you need to build a complex path with several backward arrows then use sub-paths and
122 | /// merge them with Path.addPath (see after).
123 | {
124 | Path path = Path();
125 | path.moveTo(size.width * 0.25, 358);
126 | path.relativeLineTo(size.width * 0.13, 50);
127 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1);
128 | path.relativeLineTo(size.width * 0.13, -50);
129 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1);
130 | path.relativeLineTo(size.width * 0.08, 50);
131 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1);
132 | path.relativeLineTo(size.width * 0.08, -50);
133 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1);
134 | path.relativeLineTo(size.width * 0.04, 50);
135 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1);
136 | path.relativeLineTo(size.width * 0.04, -50);
137 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1);
138 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1, isBackward: true);
139 |
140 | canvas.drawPath(path, paint..color = Colors.cyan);
141 |
142 | const TextSpan textSpan = TextSpan(
143 | text: 'Single Path with multiple forward and one backward arrow tips.',
144 | style: TextStyle(color: Colors.cyan),
145 | );
146 | final TextPainter textPainter = TextPainter(
147 | text: textSpan,
148 | textAlign: TextAlign.center,
149 | textDirection: TextDirection.ltr,
150 | );
151 | textPainter.layout(minWidth: size.width);
152 | textPainter.paint(canvas, const Offset(0, 326));
153 | }
154 |
155 | /// Path with several backward arrow and one forward arrow.
156 | /// IMPORTANT: Due to limitations of the Path API this can only be achieved reliably by using sub-paths.
157 | {
158 | Path path = Path();
159 | Offset penPosition = Offset(size.width * 0.25, 470);
160 | path.moveTo(penPosition.dx, penPosition.dy);
161 | penPosition += Offset(size.width * 0.13, 50);
162 | path.lineTo(penPosition.dx, penPosition.dy);
163 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1, isBackward: true);
164 |
165 | Path subPath = Path();
166 | subPath.moveTo(penPosition.dx, penPosition.dy);
167 | penPosition += Offset(size.width * 0.13, -50);
168 | subPath.lineTo(penPosition.dx, penPosition.dy);
169 | subPath = ArrowPath.addTip(subPath, tipAngle: math.pi * 0.1, isBackward: true);
170 | path.addPath(subPath, Offset.zero);
171 |
172 | subPath = Path();
173 | subPath.moveTo(penPosition.dx, penPosition.dy);
174 | penPosition += Offset(size.width * 0.08, 50);
175 | subPath.lineTo(penPosition.dx, penPosition.dy);
176 | subPath = ArrowPath.addTip(subPath, tipAngle: math.pi * 0.1, isBackward: true);
177 | path.addPath(subPath, Offset.zero);
178 |
179 | subPath = Path();
180 | subPath.moveTo(penPosition.dx, penPosition.dy);
181 | penPosition += Offset(size.width * 0.08, -50);
182 | subPath.lineTo(penPosition.dx, penPosition.dy);
183 | subPath = ArrowPath.addTip(subPath, tipAngle: math.pi * 0.1, isBackward: true);
184 | path.addPath(subPath, Offset.zero);
185 |
186 | subPath = Path();
187 | subPath.moveTo(penPosition.dx, penPosition.dy);
188 | penPosition += Offset(size.width * 0.04, 50);
189 | subPath.lineTo(penPosition.dx, penPosition.dy);
190 | subPath = ArrowPath.addTip(subPath, tipAngle: math.pi * 0.1, isBackward: true);
191 | path.addPath(subPath, Offset.zero);
192 |
193 | subPath = Path();
194 | subPath.moveTo(penPosition.dx, penPosition.dy);
195 | penPosition += Offset(size.width * 0.04, -50);
196 | subPath.lineTo(penPosition.dx, penPosition.dy);
197 | subPath = ArrowPath.addTip(subPath, tipAngle: math.pi * 0.1, isBackward: true);
198 | path.addPath(subPath, Offset.zero);
199 |
200 | path = ArrowPath.addTip(path, tipAngle: math.pi * 0.1);
201 |
202 | canvas.drawPath(path, paint..color = Colors.blue);
203 |
204 | const TextSpan textSpan = TextSpan(
205 | text: 'Single Path with multiple backward arrow tips.',
206 | style: TextStyle(color: Colors.blue),
207 | );
208 | final TextPainter textPainter = TextPainter(
209 | text: textSpan,
210 | textAlign: TextAlign.center,
211 | textDirection: TextDirection.ltr,
212 | );
213 | textPainter.layout(minWidth: size.width);
214 | textPainter.paint(canvas, const Offset(0, 436));
215 | }
216 |
217 | /// Adjusted
218 | {
219 | Path path = Path();
220 | path.moveTo(size.width * 0.1, 590);
221 | path.relativeCubicTo(0, 0, size.width * 0.3, 50, size.width * 0.25, 75);
222 | path = ArrowPath.addTip(path, isAdjusted: true);
223 | canvas.drawPath(path, paint..color = Colors.cyan);
224 |
225 | const TextSpan textSpan = TextSpan(
226 | text: 'Adjusted',
227 | style: TextStyle(color: Colors.cyan),
228 | );
229 | final TextPainter textPainter = TextPainter(
230 | text: textSpan,
231 | textAlign: TextAlign.left,
232 | textDirection: TextDirection.ltr,
233 | );
234 | textPainter.layout();
235 | textPainter.paint(canvas, Offset(size.width * 0.2, 572));
236 | }
237 |
238 | /// Non adjusted.
239 | {
240 | Path path = Path();
241 | path.moveTo(size.width * 0.6, 590);
242 | path.relativeCubicTo(0, 0, size.width * 0.3, 50, size.width * 0.25, 75);
243 | path = ArrowPath.addTip(path, isAdjusted: false);
244 |
245 | canvas.drawPath(path, paint..color = Colors.cyan);
246 |
247 | const TextSpan textSpan = TextSpan(
248 | text: 'Non adjusted',
249 | style: TextStyle(color: Colors.cyan),
250 | );
251 | final TextPainter textPainter = TextPainter(
252 | text: textSpan,
253 | textAlign: TextAlign.left,
254 | textDirection: TextDirection.ltr,
255 | );
256 | textPainter.layout();
257 | textPainter.paint(canvas, Offset(size.width * 0.65, 572));
258 | }
259 | }
260 |
261 | @override
262 | bool shouldRepaint(ArrowPainter oldDelegate) => false;
263 | }
264 |
--------------------------------------------------------------------------------
/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | arrow_path:
5 | dependency: "direct main"
6 | description:
7 | path: ".."
8 | relative: true
9 | source: path
10 | version: "3.1.0"
11 | characters:
12 | dependency: transitive
13 | description:
14 | name: characters
15 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
16 | url: "https://pub.dev"
17 | source: hosted
18 | version: "1.3.0"
19 | collection:
20 | dependency: transitive
21 | description:
22 | name: collection
23 | sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
24 | url: "https://pub.dev"
25 | source: hosted
26 | version: "1.17.1"
27 | flutter:
28 | dependency: "direct main"
29 | description: flutter
30 | source: sdk
31 | version: "0.0.0"
32 | flutter_lints:
33 | dependency: "direct dev"
34 | description:
35 | name: flutter_lints
36 | sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
37 | url: "https://pub.dev"
38 | source: hosted
39 | version: "2.0.1"
40 | js:
41 | dependency: transitive
42 | description:
43 | name: js
44 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
45 | url: "https://pub.dev"
46 | source: hosted
47 | version: "0.6.7"
48 | lints:
49 | dependency: transitive
50 | description:
51 | name: lints
52 | sha256: "5cfd6509652ff5e7fe149b6df4859e687fca9048437857cb2e65c8d780f396e3"
53 | url: "https://pub.dev"
54 | source: hosted
55 | version: "2.0.0"
56 | material_color_utilities:
57 | dependency: transitive
58 | description:
59 | name: material_color_utilities
60 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
61 | url: "https://pub.dev"
62 | source: hosted
63 | version: "0.2.0"
64 | meta:
65 | dependency: transitive
66 | description:
67 | name: meta
68 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
69 | url: "https://pub.dev"
70 | source: hosted
71 | version: "1.9.1"
72 | sky_engine:
73 | dependency: transitive
74 | description: flutter
75 | source: sdk
76 | version: "0.0.99"
77 | vector_math:
78 | dependency: transitive
79 | description:
80 | name: vector_math
81 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
82 | url: "https://pub.dev"
83 | source: hosted
84 | version: "2.1.4"
85 | sdks:
86 | dart: ">=3.0.0-0 <4.0.0"
87 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: arrow_path_example
2 | description: Example project for the arrow_path package.
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'
7 |
8 | version: 1.0.1+2
9 |
10 | environment:
11 | sdk: ">=2.12.0 <4.0.0"
12 |
13 | dependencies:
14 | flutter:
15 | sdk: flutter
16 | arrow_path:
17 | path: ../
18 |
19 | dev_dependencies:
20 | flutter_lints: ^2.0.1
21 |
--------------------------------------------------------------------------------
/lib/arrow_path.dart:
--------------------------------------------------------------------------------
1 | library arrow_path;
2 |
3 | import 'dart:math' as math;
4 | import 'dart:ui';
5 |
6 | class ArrowPath {
7 | /// Add an arrow to the end of the last drawn curve in the given path.
8 | ///
9 | /// The returned path is moved to the end of the curve. Always add the arrow before moving the path, not after, else the move will be lost.
10 | /// After adding the arrow you can move the path, draw more and apply an arrow to the new drawn part.
11 | ///
12 | /// If [isDoubleSided] is true (default to false), an arrow will also be added to the beginning of the first drawn curve.
13 | ///
14 | /// [tipLength] is the length (in pixels) of each of the 2 lines making the arrow.
15 | ///
16 | /// [tipAngle] is the angle (in radians) between each of the 2 lines making the arrow and the curve at this point.
17 | ///
18 | /// If [isAdjusted] is true (default to true), the tip of the arrow will be rotated (not following the tangent perfectly).
19 | /// This improves the look of the arrow when the end of the curve as a strong curvature.
20 | /// Can be disabled to save performance when the arrow is flat.
21 | ///
22 | /// If the given path is not suitable to draw the arrow head (for example if the path as no length) then the path will be returned unchanged.
23 | @Deprecated('This is deprecated and will be removed in a future release. Use ArrowPath.addTip instead.')
24 | static Path make({
25 | required Path path,
26 | double tipLength = 15,
27 | double tipAngle = math.pi * 0.2,
28 | bool isDoubleSided = false,
29 | bool isAdjusted = true,
30 | }) {
31 | final List pathMetrics = path.computeMetrics().toList();
32 | if (pathMetrics.isEmpty) {
33 | /// This can happen if the path as no length (trying to draw an arrow that is too small, like less than 1 pixel).
34 | return path;
35 | }
36 |
37 | tipAngle = math.pi - tipAngle;
38 | final PathMetric lastPathMetric = pathMetrics.last;
39 | final PathMetric firstPathMetric = pathMetrics.first;
40 |
41 | final Tangent? tangentLastPath = lastPathMetric.getTangentForOffset(lastPathMetric.length);
42 |
43 | if (tangentLastPath == null) {
44 | /// This should never happen.
45 | return path;
46 | }
47 |
48 | final Offset originalPosition = tangentLastPath.position;
49 |
50 | double adjustmentAngle = 0;
51 | if (isAdjusted && lastPathMetric.length > 10) {
52 | final Tangent tanBefore = lastPathMetric.getTangentForOffset(lastPathMetric.length - 5)!;
53 | adjustmentAngle = _getAngleBetweenVectors(tangentLastPath.vector, tanBefore.vector);
54 | }
55 |
56 | _addFullArrowTip(
57 | path: path,
58 | tangentVector: tangentLastPath.vector,
59 | tangentPosition: tangentLastPath.position,
60 | tipLength: tipLength,
61 | tipAngle: tipAngle,
62 | adjustmentAngle: adjustmentAngle,
63 | );
64 |
65 | if (isDoubleSided) {
66 | /// This path is double side, add the other arrow tip.
67 | final Tangent? tangentFirstPath = firstPathMetric.getTangentForOffset(0);
68 | if (tangentFirstPath != null) {
69 | if (isAdjusted && firstPathMetric.length > 10) {
70 | final Tangent tanBefore = firstPathMetric.getTangentForOffset(5)!;
71 | adjustmentAngle = _getAngleBetweenVectors(tangentFirstPath.vector, tanBefore.vector);
72 | }
73 |
74 | _addFullArrowTip(
75 | path: path,
76 | tangentVector: -tangentFirstPath.vector,
77 | tangentPosition: tangentFirstPath.position,
78 | tipLength: tipLength,
79 | tipAngle: tipAngle,
80 | adjustmentAngle: adjustmentAngle,
81 | );
82 | }
83 | }
84 |
85 | path.moveTo(originalPosition.dx, originalPosition.dy);
86 |
87 | return path;
88 | }
89 |
90 | /// Add an arrow to the end of the last drawn curve in the given path.
91 | ///
92 | /// The returned path is moved to the end of the curve. Always add the arrow before moving the path, not after, else the move will be lost.
93 | /// After adding the arrow you can move the path, draw more and apply an arrow to the new drawn part.
94 | ///
95 | /// If [isBackward] is true (default to false), the arrow will be added to the beginning of the first drawn curve instead of the end.
96 | /// This should never be called more than once on the same path. If you want to make a path with several backward arrows then use sub-paths and
97 | /// merge them with [Path.addPath].
98 | ///
99 | /// [tipLength] is the length (in pixels) of each of the 2 lines making the arrow.
100 | ///
101 | /// [tipAngle] is the angle (in radians) between each of the 2 lines making the arrow and the curve at this point.
102 | ///
103 | /// If [isAdjusted] is true (default to true), the tip of the arrow will be rotated (not following the tangent perfectly).
104 | /// This improves the look of the arrow when the end of the curve as a strong curvature.
105 | /// Can be disabled to save performance when the arrow is flat.
106 | ///
107 | /// If the given path is not suitable to draw the arrow head (for example if the path as no length) then the path will be returned unchanged.
108 | static Path addTip(
109 | Path path, {
110 | double tipLength = 15,
111 | double tipAngle = math.pi * 0.2,
112 | bool isBackward = false,
113 | bool isAdjusted = true,
114 | }) {
115 | path = Path.from(path);
116 |
117 | final List pathMetrics = path.computeMetrics().toList();
118 | if (pathMetrics.isEmpty) {
119 | /// This can happen if the path as no length (trying to draw an arrow that is too small, like less than 1 pixel).
120 | return path;
121 | }
122 |
123 | final Offset? originalPosition = _getPathEndPosition(pathMetrics);
124 | if (originalPosition == null) {
125 | /// This should never happen.
126 | return path;
127 | }
128 |
129 | tipAngle = math.pi - tipAngle;
130 | final PathMetric pathMetric = isBackward ? pathMetrics.first : pathMetrics.last;
131 |
132 | final Tangent? tangent = pathMetric.getTangentForOffset(isBackward ? 0 : pathMetric.length);
133 | if (tangent == null) {
134 | /// This should never happen.
135 | return path;
136 | }
137 |
138 | double adjustmentAngle = 0;
139 | if (isAdjusted && pathMetric.length > 10) {
140 | final Tangent tangentBefore = pathMetric.getTangentForOffset(isBackward ? 5 : pathMetric.length - 5)!;
141 | adjustmentAngle = _getAngleBetweenVectors(tangent.vector, tangentBefore.vector);
142 | }
143 |
144 | if (isBackward) {
145 | /// Using a temporary [Path] and [Path.addPath] because we want the backward arrow to always be at the start of the [PathMetrics].
146 | /// This is important because calling [Path.moveTo] does NOT actually create a segment, so the move information is lost we next read [PathMetrics].
147 | /// See [_getPathEndPosition] for more info.
148 | final tempoPath = Path();
149 |
150 | tempoPath.moveTo(tangent.position.dx, tangent.position.dy);
151 |
152 | _addFullArrowTip(
153 | path: tempoPath,
154 | tangentVector: -tangent.vector,
155 | tangentPosition: tangent.position,
156 | tipLength: tipLength,
157 | tipAngle: tipAngle,
158 | adjustmentAngle: adjustmentAngle,
159 | );
160 | tempoPath.addPath(path, Offset.zero);
161 | return tempoPath;
162 | } else {
163 | _addFullArrowTip(
164 | path: path,
165 | tangentVector: tangent.vector,
166 | tangentPosition: tangent.position,
167 | tipLength: tipLength,
168 | tipAngle: tipAngle,
169 | adjustmentAngle: adjustmentAngle,
170 | );
171 | }
172 |
173 | return path;
174 | }
175 |
176 | static void _addFullArrowTip({
177 | required Path path,
178 | required Offset tangentVector,
179 | required Offset tangentPosition,
180 | required double tipLength,
181 | required double tipAngle,
182 | required double adjustmentAngle,
183 | }) {
184 | _addPartialArrowTip(
185 | tangentVector: tangentVector,
186 | tangentPosition: tangentPosition,
187 | path: path,
188 | tipLength: tipLength,
189 | tipAngle: tipAngle,
190 | adjustmentAngle: adjustmentAngle,
191 | );
192 | _addPartialArrowTip(
193 | tangentVector: tangentVector,
194 | tangentPosition: tangentPosition,
195 | path: path,
196 | tipLength: tipLength,
197 | tipAngle: -tipAngle,
198 | adjustmentAngle: adjustmentAngle,
199 | );
200 | }
201 |
202 | /// We need to make sure we end by drawing back to the start position, because simply doing a moveTo does NOT save to
203 | /// the [PathMetrics], so the move is lost and this causes issues for successive arrow tip drawings.
204 | static void _addPartialArrowTip({
205 | required Path path,
206 | required Offset tangentVector,
207 | required Offset tangentPosition,
208 | required double tipLength,
209 | required double tipAngle,
210 | required double adjustmentAngle,
211 | }) {
212 | final Offset tipVector = _rotateVector(tangentVector, tipAngle - adjustmentAngle) * tipLength;
213 | path.relativeMoveTo(tipVector.dx, tipVector.dy);
214 | path.relativeLineTo(-tipVector.dx, -tipVector.dy);
215 | }
216 |
217 | /// Defining the Path end is tricky, ideally we would want to get the position of the last moveTo from the Path, but his is not
218 | /// possible (there is no way to get that from the Path API).
219 | /// Instead we have to use the last PathMetric (the segment that was last drawn) and hope it is what we want it to be.
220 | /// This would fails for example if we where adding the backward arrow directly to the end of the path, because even doing
221 | /// a moveTo back to the end of the path (before we added the arrow tip) would not allow us to get the right position if
222 | /// we try to draw a forward arrow straight after. Instead, the forward arrow would be draw at the last lineTo position (not the
223 | /// last moveTo position), which would happen to be at the start of the path (since it's were we last drawn something).
224 | /// This is why we use a temporary path to draw the backward arrow tip, and we add the path as a sub-path
225 | /// of the temporary path. Then we reassign the path with `path = subpath`. This allow us to have the backward arrow at
226 | /// the start of the PathMetrics, rather than the end, and then we can draw any following forward arrow correctly.
227 | static Offset? _getPathEndPosition(List pathMetrics) {
228 | final Tangent? tangent = pathMetrics.last.getTangentForOffset(pathMetrics.last.length);
229 |
230 | if (tangent == null) {
231 | /// This should never happen.
232 | return null;
233 | }
234 |
235 | return tangent.position;
236 | }
237 |
238 | static Offset _rotateVector(Offset vector, double angle) => Offset(
239 | math.cos(angle) * vector.dx - math.sin(angle) * vector.dy,
240 | math.sin(angle) * vector.dx + math.cos(angle) * vector.dy,
241 | );
242 |
243 | static double _getVectorsDotProduct(Offset vector1, Offset vector2) =>
244 | vector1.dx * vector2.dx + vector1.dy * vector2.dy;
245 |
246 | /// Clamp to avoid rounding issues when the 2 vectors are equal.
247 | static double _getAngleBetweenVectors(Offset vector1, Offset vector2) => math.acos(
248 | (_getVectorsDotProduct(vector1, vector2) / (vector1.distance * vector2.distance)).clamp(-1.0, 1.0),
249 | );
250 | }
251 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | characters:
5 | dependency: transitive
6 | description:
7 | name: characters
8 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "1.3.0"
12 | collection:
13 | dependency: transitive
14 | description:
15 | name: collection
16 | sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "1.17.1"
20 | flutter:
21 | dependency: "direct main"
22 | description: flutter
23 | source: sdk
24 | version: "0.0.0"
25 | flutter_lints:
26 | dependency: "direct dev"
27 | description:
28 | name: flutter_lints
29 | sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
30 | url: "https://pub.dev"
31 | source: hosted
32 | version: "2.0.1"
33 | js:
34 | dependency: transitive
35 | description:
36 | name: js
37 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
38 | url: "https://pub.dev"
39 | source: hosted
40 | version: "0.6.7"
41 | lints:
42 | dependency: transitive
43 | description:
44 | name: lints
45 | sha256: "5cfd6509652ff5e7fe149b6df4859e687fca9048437857cb2e65c8d780f396e3"
46 | url: "https://pub.dev"
47 | source: hosted
48 | version: "2.0.0"
49 | material_color_utilities:
50 | dependency: transitive
51 | description:
52 | name: material_color_utilities
53 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
54 | url: "https://pub.dev"
55 | source: hosted
56 | version: "0.2.0"
57 | meta:
58 | dependency: transitive
59 | description:
60 | name: meta
61 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
62 | url: "https://pub.dev"
63 | source: hosted
64 | version: "1.9.1"
65 | sky_engine:
66 | dependency: transitive
67 | description: flutter
68 | source: sdk
69 | version: "0.0.99"
70 | vector_math:
71 | dependency: transitive
72 | description:
73 | name: vector_math
74 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
75 | url: "https://pub.dev"
76 | source: hosted
77 | version: "2.1.4"
78 | sdks:
79 | dart: ">=3.0.0-0 <4.0.0"
80 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: arrow_path
2 | description: Draw arrows with Path objects easily. Paths can be composited to add arrows to any curve and draw all at once.
3 | version: 3.1.0
4 | homepage: https://github.com/quentinleguennec/flutter-arrow-path.git
5 |
6 | environment:
7 | sdk: ">=2.12.0 <4.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 |
13 | dev_dependencies:
14 | flutter_lints: ^2.0.1
15 |
--------------------------------------------------------------------------------