├── .gitattributes
├── .github
└── stale.yml
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── SECURITY.md
├── analysis_options.yaml
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ │ └── dev
│ │ │ │ │ └── leadcode
│ │ │ │ │ └── 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
├── assets
│ └── i18n
│ │ ├── ar.json
│ │ ├── en.json
│ │ ├── es.json
│ │ └── ru.json
├── ios
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner-Bridging-Header.h
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── 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.yaml
├── web
│ ├── favicon.png
│ ├── icons
│ │ ├── Icon-192.png
│ │ └── Icon-512.png
│ ├── index.html
│ └── manifest.json
└── windows
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
│ └── runner
│ ├── CMakeLists.txt
│ ├── Runner.rc
│ ├── flutter_window.cpp
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── resource.h
│ ├── resources
│ └── app_icon.ico
│ ├── run_loop.cpp
│ ├── run_loop.h
│ ├── runner.exe.manifest
│ ├── utils.cpp
│ ├── utils.h
│ ├── win32_window.cpp
│ └── win32_window.h
├── lib
├── flutter_translate.dart
└── src
│ ├── constants
│ └── constants.dart
│ ├── delegates
│ └── localization_delegate.dart
│ ├── interfaces
│ └── translate_preferences.dart
│ ├── services
│ ├── locale_file_service.dart
│ ├── locale_service.dart
│ ├── localization.dart
│ └── localization_configuration.dart
│ ├── utils
│ ├── device_locale.dart
│ └── utils.dart
│ ├── validators
│ └── configuration_validator.dart
│ └── widgets
│ ├── localization_provider.dart
│ ├── localized_app.dart
│ └── localized_app_state.dart
├── pubspec.yaml
└── resources
├── gifs
└── flutter_translate_screen.gif
└── images
└── flutter_translate.png
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.cmake linguist-detectable=false
2 | *.h linguist-detectable=false
3 | *.cpp linguist-detectable=false
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 60
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - pinned
8 | - security
9 | # Label to use when marking an issue as stale
10 | staleLabel: wontfix
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: >
13 | This issue has been automatically marked as stale because it has not had
14 | recent activity. It will be closed if no further activity occurs. Thank you
15 | for your contributions.
16 | # Comment to post when closing a stale issue. Set to `false` to disable
17 | closeComment: false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .packages
28 | .pub-cache/
29 | .pub/
30 | build/
31 |
32 | # Android related
33 | **/android/**/gradle-wrapper.jar
34 | **/android/.gradle
35 | **/android/captures/
36 | **/android/gradlew
37 | **/android/gradlew.bat
38 | **/android/local.properties
39 | **/android/**/GeneratedPluginRegistrant.java
40 |
41 | # iOS/XCode related
42 | **/ios/**/*.mode1v3
43 | **/ios/**/*.mode2v3
44 | **/ios/**/*.moved-aside
45 | **/ios/**/*.pbxuser
46 | **/ios/**/*.perspectivev3
47 | **/ios/**/*sync/
48 | **/ios/**/.sconsign.dblite
49 | **/ios/**/.tags*
50 | **/ios/**/.vagrant/
51 | **/ios/**/DerivedData/
52 | **/ios/**/Icon?
53 | **/ios/**/Pods/
54 | **/ios/**/.symlinks/
55 | **/ios/**/profile
56 | **/ios/**/xcuserdata
57 | **/ios/.generated/
58 | **/ios/Flutter/App.framework
59 | **/ios/Flutter/Flutter.framework
60 | **/ios/Flutter/Generated.xcconfig
61 | **/ios/Flutter/app.flx
62 | **/ios/Flutter/app.zip
63 | **/ios/Flutter/flutter_assets/
64 | **/ios/Flutter/flutter_export_environment.sh
65 | **/ios/ServiceDefinitions.json
66 | **/ios/Runner/GeneratedPluginRegistrant.*
67 |
68 | # Exceptions to above rules.
69 | !**/ios/**/default.mode1v3
70 | !**/ios/**/default.mode2v3
71 | !**/ios/**/default.pbxuser
72 | !**/ios/**/default.perspectivev3
73 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
74 | pubspec.lock
75 | example_static_keys/lib/generated_plugin_registrant.dart
76 | example_static_keys/.flutter-plugins-dependencies
77 | example/lib/generated_plugin_registrant.dart
78 |
--------------------------------------------------------------------------------
/.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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5
8 | channel: stable
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [1.0.0]
2 |
3 | - Initial release.
4 |
5 | ## [1.0.1]
6 |
7 | - Removed the flutter_localizations dependency.
8 |
9 | ## [1.0.2]
10 |
11 | - Simplified the localization initialization.
12 |
13 | ## [1.1.0]
14 |
15 | - Implemented a global translate method.
16 | - Removed the static Translate class.
17 | - Localization is now a singleton.
18 |
19 | ## [1.2.0]
20 |
21 | - Implemented pluralization.
22 | - Fixed multiple issues.
23 | - translate, translatePlural and changeLanguage methods are now global.
24 |
25 | ## [1.2.2]
26 |
27 | - Missing localizations now return the full key path.
28 |
29 | ## [1.2.5]
30 |
31 | - Fixed possible exception when adding an extra slash to the ```basePath```
32 |
33 | ## [1.3.0]
34 |
35 | - Implemented the onLocaleChanged callback
36 |
37 | ## [1.3.1]
38 |
39 | - Implemented the localeToString method
40 |
41 | ## [1.3.2]
42 |
43 | - Fixed some callback issues for onLocaleChanged
44 |
45 | ## [1.4.0]
46 |
47 | - Implemented support for automatically saving & restoring the selected locale using shared preferences
48 |
49 | ## [1.4.0+1]
50 |
51 | - Added the Awesome Flutter badge
52 |
53 | ## [1.4.0+2]
54 |
55 | - Fixed the example to adapt the changes to BinaryMessenger (https://github.com/flutter/flutter/pull/38464)
56 |
57 | ## [1.5.0]
58 |
59 | - Fixed the blackscreen issue on startup
60 | - Fixed the iOS issue regarding the device locale
61 | - The current device locale is now used on startup
62 |
63 | ## [1.5.1]
64 |
65 | - Updated the flutter_device_locale dependency to avoid a possible exception
66 | - Updated the example to AndroidX
67 |
68 | ## [1.5.2]
69 |
70 | - Updated the flutter_device_locale version
71 |
72 | ## [1.5.3]
73 |
74 | - Renamed packages, updated license and links
75 |
76 | ## [1.5.7]
77 |
78 | - Updated the examples
79 | - Fixed some issues with flutter_device_locale and swift
80 |
81 | ## [1.6.0]
82 |
83 | - Web applications are now supported
84 | - Updated the examples with web support
85 |
86 | ## [2.0.0]
87 |
88 | - Removed flutter_device_locale dependency
89 | - The native flutter locale retrieval method is now used
90 | - Added support for desktop
91 | - Added examples for windows desktop
92 |
93 | ## [2.0.1]
94 |
95 | - Fixed web support
96 |
97 | ## [3.0.0]
98 |
99 | - Null safety support
100 |
101 | ## [3.0.1]
102 |
103 | - Code format
104 |
105 | ## [3.1.0]
106 |
107 | - Updated dependencies
108 |
109 | ## [4.0.0]
110 |
111 | - Plurals functionality is now based on Intl rules (https://api.flutter.dev/flutter/intl/Intl/plural.html)
112 | - Supported formats are: zero, one, two, few, many, other
113 |
114 | ## [4.0.2]
115 |
116 | - Fixed null safety compile issue
117 |
118 | ## [4.0.3]
119 |
120 | - Fixed null-aware operation exception
121 |
122 | ## [4.0.4]
123 |
124 | - Bump intl version to support latest Flutter version
125 |
126 | ## [4.1.0]
127 |
128 | - Upgraded packages and SDK version
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Jesway Labs, LLC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [
](https://github.com/Jesway/Flutter-Translate/)
3 |
4 | [](https://pub.dev/packages/flutter_translate)
5 |
6 |
7 |
8 | [](https://github.com/Jesway/Flutter-Translate/blob/master/LICENSE)
9 | [](https://flutter.io/)
10 |
11 | ---
12 |
13 | Flutter Translate is a fully featured localization / internationalization (i18n) library for Flutter.
14 |
15 | It lets you define translations for your content in different languages and switch between them easily.
16 |
17 | ## Example
18 |
19 |
20 | ## Features
21 |
22 | * Very easy to use
23 | * ```Mobile```, ```Web``` and ```Desktop``` support
24 | * ```Pluralization``` and ```Duals``` support
25 | * Supports both ``languageCode (en)`` and ``languageCode_countryCode (en_US)`` locale formats
26 | * Automatically ```save & restore``` the selected locale [with a simple implementation](https://github.com/Jesway/Flutter-Translate/wiki/2.-Automatically-saving-&-restoring-the-selected-locale)
27 | * Full support for ```right-to-left``` locales
28 | * ``Fallback`` locale support in case the system locale is unsupported
29 | * Supports both ``inline or nested`` JSON
30 |
31 | ## Documentation
32 |
33 | Complete documentation is available [on the wiki page](https://github.com/Jesway/Flutter-Translate/wiki).
34 |
35 | To get started please see [Installation, Configuration & Usage](https://github.com/Jesway/Flutter-Translate/wiki/1.-Installation,-Configuration-&-Usage).
36 |
37 | ## Example
38 |
39 | https://github.com/Jesway/Flutter-Translate/tree/master/example
40 |
41 | ## Issues
42 | Please file any issues, bugs or feature request [here](https://github.com/Jesway/Flutter-Translate/issues).
43 |
44 | ## License
45 |
46 | This project is licensed under the [MIT License](https://github.com/Jesway/Flutter-Translate/blob/master/LICENSE)
47 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | In our commitment to maintain the security of the Flutter Translate project, we focus on providing security updates only to the most recent MAJOR.MINOR version. We do not backport security patches to earlier versions. To ensure you have the latest security enhancements, always keep your Flutter Translate installation updated to the latest release.
6 |
7 | ## Reporting a Vulnerability
8 |
9 | Should you discover a security vulnerability within Flutter Translate, we encourage a responsible disclosure. Please send a detailed report of your findings to security@jesway.com. Our team will promptly investigate and address the issue as swiftly as possible.
10 |
11 | We greatly appreciate the efforts of individuals who contribute to the security of our project. While we currently do not offer a bounty program, every report, be it a minor bug or a significant security flaw, is invaluable in enhancing Flutter Translate for all users. We extend our heartfelt thanks to those who assist us in this crucial aspect of software maintenance.
12 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | analyzer:
2 | # enable-experiment:
3 | # - non-nullable
4 |
--------------------------------------------------------------------------------
/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 | .dart_tool/
26 | .flutter-plugins
27 | .flutter-plugins-dependencies
28 | .packages
29 | .pub-cache/
30 | .pub/
31 | /build/
32 |
33 | # Android related
34 | **/android/**/gradle-wrapper.jar
35 | **/android/.gradle
36 | **/android/captures/
37 | **/android/gradlew
38 | **/android/gradlew.bat
39 | **/android/local.properties
40 | **/android/**/GeneratedPluginRegistrant.java
41 |
42 | # iOS/XCode related
43 | **/ios/**/*.mode1v3
44 | **/ios/**/*.mode2v3
45 | **/ios/**/*.moved-aside
46 | **/ios/**/*.pbxuser
47 | **/ios/**/*.perspectivev3
48 | **/ios/**/*sync/
49 | **/ios/**/.sconsign.dblite
50 | **/ios/**/.tags*
51 | **/ios/**/.vagrant/
52 | **/ios/**/DerivedData/
53 | **/ios/**/Icon?
54 | **/ios/**/Pods/
55 | **/ios/**/.symlinks/
56 | **/ios/**/profile
57 | **/ios/**/xcuserdata
58 | **/ios/.generated/
59 | **/ios/Flutter/App.framework
60 | **/ios/Flutter/Flutter.framework
61 | **/ios/Flutter/Generated.xcconfig
62 | **/ios/Flutter/app.flx
63 | **/ios/Flutter/app.zip
64 | **/ios/Flutter/flutter_assets/
65 | **/ios/Flutter/flutter_export_environment.sh
66 | **/ios/ServiceDefinitions.json
67 | **/ios/Runner/GeneratedPluginRegistrant.*
68 |
69 | # Exceptions to above rules.
70 | !**/ios/**/default.mode1v3
71 | !**/ios/**/default.mode2v3
72 | !**/ios/**/default.pbxuser
73 | !**/ios/**/default.perspectivev3
74 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
75 |
--------------------------------------------------------------------------------
/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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # example
2 |
3 | Example project for the flutter_translate library
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 28
29 |
30 | lintOptions {
31 | disable 'InvalidPackage'
32 | }
33 |
34 | defaultConfig {
35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
36 | applicationId "dev.com.jesway.example"
37 | minSdkVersion 16
38 | targetSdkVersion 28
39 | versionCode flutterVersionCode.toInteger()
40 | versionName flutterVersionName
41 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
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 | testImplementation 'junit:junit:4.12'
59 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
60 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
61 | }
62 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
13 |
20 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/dev/leadcode/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package dev.com.jesway.example;
2 |
3 | import android.os.Bundle;
4 | import io.flutter.app.FlutterActivity;
5 | import io.flutter.plugins.GeneratedPluginRegistrant;
6 |
7 | public class MainActivity extends FlutterActivity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | GeneratedPluginRegistrant.registerWith(this);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.2.1'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
3 | android.enableR8=true
4 | android.useAndroidX=true
5 | android.enableJetifier=true
6 |
--------------------------------------------------------------------------------
/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-4.10.2-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/assets/i18n/ar.json:
--------------------------------------------------------------------------------
1 | {
2 | "app_bar":
3 | {
4 | "title": "مرحباً بك في الصفحة الرئيسية"
5 | },
6 | "button":
7 | {
8 | "cancel": "إلغاء",
9 | "change_language": "تغيير اللغة"
10 | },
11 | "language":
12 | {
13 | "name":
14 | {
15 | "en": "الانجليزية",
16 | "es": "الاسبانية",
17 | "fa": "الفارسية",
18 | "ar": "العربية",
19 | "ru": "الروسية"
20 | },
21 | "selected_message": "اللغة المختارة حالياً هي {language}",
22 | "selection":
23 | {
24 | "message": "برجاء إختيار لغة من القائمة",
25 | "title": "إختيار اللغة"
26 | }
27 | },
28 | "plural":
29 | {
30 | "demo":
31 | {
32 | "zero": "برجاء البدء في الضغط على زر الإضافة",
33 | "one": "لقد ضغطت الزر مرة",
34 | "two": "لقد ضغطت الزر مرتين",
35 | "other": "لقد ضغطت الزر {{value}} مرة"
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/example/assets/i18n/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "app_bar":
3 | {
4 | "title": "Welcome to the home page"
5 | },
6 | "button":
7 | {
8 | "cancel": "Cancel",
9 | "change_language": "Change Language"
10 | },
11 | "language":
12 | {
13 | "name":
14 | {
15 | "en": "English",
16 | "es": "Spanish",
17 | "fa": "Persian",
18 | "ar": "Arabic",
19 | "ru": "Russian"
20 | },
21 | "selected_message": "Currently selected language is {language}",
22 | "selection":
23 | {
24 | "message": "Please select a language from the list",
25 | "title": "Language Selection"
26 | }
27 | },
28 | "plural":
29 | {
30 | "demo":
31 | {
32 | "zero": "Please start pushing the 'plus' button.",
33 | "one": "You have pushed the button one time.",
34 | "two": "You have pushed the button two times.",
35 | "other": "You have pushed the button {{value}} times."
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/example/assets/i18n/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "app_bar":
3 | {
4 | "title": "Bienvenido a la página de inicio"
5 | },
6 | "button":
7 | {
8 | "cancel": "Cancelar",
9 | "change_language": "Cambiar idioma"
10 | },
11 | "language":
12 | {
13 | "name":
14 | {
15 | "en": "Inglés",
16 | "es": "Español",
17 | "fa": "Persa",
18 | "ar": "Arábica",
19 | "ru": "Ruso"
20 | },
21 | "selected_message": "El idioma seleccionado actualmente es {language}",
22 | "selection":
23 | {
24 | "message": "Por favor seleccione un idioma de la lista",
25 | "title": "Selección de idioma"
26 | }
27 | },
28 | "plural":
29 | {
30 | "demo":
31 | {
32 | "zero": "Por favor, comience a presionar el botón 'más'.",
33 | "one": "Has pulsado el botón una vez.",
34 | "two": "Has pulsado el botón dos veces.",
35 | "other": "Ha pulsado el botón {{value}} veces."
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/example/assets/i18n/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "app_bar":
3 | {
4 | "title": "Приветствуем на домашней странице"
5 | },
6 | "button":
7 | {
8 | "cancel": "Отмена",
9 | "change_language": "Сменить Язык"
10 | },
11 | "language":
12 | {
13 | "name":
14 | {
15 | "en": "Английский",
16 | "es": "Испанский",
17 | "fa": "Персидский",
18 | "ar": "Арабский",
19 | "ru": "Русский"
20 | },
21 | "selected_message": "Текущий язык {language}",
22 | "selection":
23 | {
24 | "message": "Пожалуйста выберите язык из списка",
25 | "title": "Выбор Языка"
26 | }
27 | },
28 | "plural":
29 | {
30 | "demo":
31 | {
32 | "zero": "Нажимайте кнопку 'плюс'.",
33 | "one": "Кнопка плюс нажата {{value}} раз.",
34 | "two": "Кнопка плюс нажата {{value}} раза.",
35 | "few": "Кнопка плюс нажата {{value}} раза.",
36 | "many": "Кнопка плюс нажата {{value}} раз.",
37 | "other": "Кнопка плюс нажата {{value}} раз."
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def parse_KV_file(file, separator='=')
14 | file_abs_path = File.expand_path(file)
15 | if !File.exists? file_abs_path
16 | return [];
17 | end
18 | pods_ary = []
19 | skip_line_start_symbols = ["#", "/"]
20 | File.foreach(file_abs_path) { |line|
21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
22 | plugin = line.split(pattern=separator)
23 | if plugin.length == 2
24 | podname = plugin[0].strip()
25 | path = plugin[1].strip()
26 | podpath = File.expand_path("#{path}", file_abs_path)
27 | pods_ary.push({:name => podname, :path => podpath});
28 | else
29 | puts "Invalid plugin specification: #{line}"
30 | end
31 | }
32 | return pods_ary
33 | end
34 |
35 | target 'Runner' do
36 | use_frameworks!
37 |
38 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
39 | # referring to absolute paths on developers' machines.
40 | system('rm -rf .symlinks')
41 | system('mkdir -p .symlinks/plugins')
42 |
43 | # Flutter Pods
44 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
45 | if generated_xcode_build_settings.empty?
46 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
47 | end
48 | generated_xcode_build_settings.map { |p|
49 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
50 | symlink = File.join('.symlinks', 'flutter')
51 | File.symlink(File.dirname(p[:path]), symlink)
52 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
53 | end
54 | }
55 |
56 | # Plugin Pods
57 | plugin_pods = parse_KV_file('../.flutter-plugins')
58 | plugin_pods.map { |p|
59 | symlink = File.join('.symlinks', 'plugins', p[:name])
60 | File.symlink(p[:path], symlink)
61 | pod p[:name], :path => File.join(symlink, 'ios')
62 | }
63 | end
64 |
65 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
66 | install! 'cocoapods', :disable_input_output_paths => true
67 |
68 | post_install do |installer|
69 | installer.pods_project.targets.each do |target|
70 | target.build_configurations.each do |config|
71 | config.build_settings['ENABLE_BITCODE'] = 'NO'
72 | end
73 | end
74 | end
75 |
--------------------------------------------------------------------------------
/example/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - flutter_device_locale (0.0.1):
4 | - Flutter
5 |
6 | DEPENDENCIES:
7 | - Flutter (from `.symlinks/flutter/ios`)
8 | - flutter_device_locale (from `.symlinks/plugins/flutter_device_locale/ios`)
9 |
10 | EXTERNAL SOURCES:
11 | Flutter:
12 | :path: ".symlinks/flutter/ios"
13 | flutter_device_locale:
14 | :path: ".symlinks/plugins/flutter_device_locale/ios"
15 |
16 | SPEC CHECKSUMS:
17 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
18 | flutter_device_locale: bd88cfdfdcae58b2a9d5ec05389fd99631c9dca7
19 |
20 | PODFILE CHECKSUM: b6a0a141693093b304368d08511b46cf3d1d0ac5
21 |
22 | COCOAPODS: 1.7.5
23 |
--------------------------------------------------------------------------------
/example/ios/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
14 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
15 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
16 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
17 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
18 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
19 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
20 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
21 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
22 | A8AA48402C356A06BB6C7962 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEEF21C6EB80CFD18AFE5862 /* Pods_Runner.framework */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXCopyFilesBuildPhase section */
26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
27 | isa = PBXCopyFilesBuildPhase;
28 | buildActionMask = 2147483647;
29 | dstPath = "";
30 | dstSubfolderSpec = 10;
31 | files = (
32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
34 | );
35 | name = "Embed Frameworks";
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXCopyFilesBuildPhase section */
39 |
40 | /* Begin PBXFileReference section */
41 | 0A85A4DDB7F1858BC9F4D9DE /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
42 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
43 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
46 | 4EFAE310239288E3004A2075 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
47 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
48 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
49 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
50 | 96399B0060D9218C958054AE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
51 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
52 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
53 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
54 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
55 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
56 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
57 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
58 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
59 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
60 | BEEF21C6EB80CFD18AFE5862 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
61 | FB3F11CF9B1C7B3801980BAE /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
62 | /* End PBXFileReference section */
63 |
64 | /* Begin PBXFrameworksBuildPhase section */
65 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
66 | isa = PBXFrameworksBuildPhase;
67 | buildActionMask = 2147483647;
68 | files = (
69 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
70 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
71 | A8AA48402C356A06BB6C7962 /* Pods_Runner.framework in Frameworks */,
72 | );
73 | runOnlyForDeploymentPostprocessing = 0;
74 | };
75 | /* End PBXFrameworksBuildPhase section */
76 |
77 | /* Begin PBXGroup section */
78 | 4AFE5892C413A9B5977EFCCD /* Pods */ = {
79 | isa = PBXGroup;
80 | children = (
81 | FB3F11CF9B1C7B3801980BAE /* Pods-Runner.debug.xcconfig */,
82 | 0A85A4DDB7F1858BC9F4D9DE /* Pods-Runner.release.xcconfig */,
83 | 96399B0060D9218C958054AE /* Pods-Runner.profile.xcconfig */,
84 | );
85 | name = Pods;
86 | path = Pods;
87 | sourceTree = "";
88 | };
89 | 9740EEB11CF90186004384FC /* Flutter */ = {
90 | isa = PBXGroup;
91 | children = (
92 | 3B80C3931E831B6300D905FE /* App.framework */,
93 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
94 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
95 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
96 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
97 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
98 | );
99 | name = Flutter;
100 | sourceTree = "";
101 | };
102 | 97C146E51CF9000F007C117D = {
103 | isa = PBXGroup;
104 | children = (
105 | 9740EEB11CF90186004384FC /* Flutter */,
106 | 97C146F01CF9000F007C117D /* Runner */,
107 | 97C146EF1CF9000F007C117D /* Products */,
108 | 4EFAE310239288E3004A2075 /* Runner-Bridging-Header.h */,
109 | 4AFE5892C413A9B5977EFCCD /* Pods */,
110 | AA946D38C45F9768443E1E10 /* Frameworks */,
111 | );
112 | sourceTree = "";
113 | };
114 | 97C146EF1CF9000F007C117D /* Products */ = {
115 | isa = PBXGroup;
116 | children = (
117 | 97C146EE1CF9000F007C117D /* Runner.app */,
118 | );
119 | name = Products;
120 | sourceTree = "";
121 | };
122 | 97C146F01CF9000F007C117D /* Runner */ = {
123 | isa = PBXGroup;
124 | children = (
125 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
126 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
127 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
128 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
129 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
130 | 97C147021CF9000F007C117D /* Info.plist */,
131 | 97C146F11CF9000F007C117D /* Supporting Files */,
132 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
133 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
134 | );
135 | path = Runner;
136 | sourceTree = "";
137 | };
138 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
139 | isa = PBXGroup;
140 | children = (
141 | 97C146F21CF9000F007C117D /* main.m */,
142 | );
143 | name = "Supporting Files";
144 | sourceTree = "";
145 | };
146 | AA946D38C45F9768443E1E10 /* Frameworks */ = {
147 | isa = PBXGroup;
148 | children = (
149 | BEEF21C6EB80CFD18AFE5862 /* Pods_Runner.framework */,
150 | );
151 | name = Frameworks;
152 | sourceTree = "";
153 | };
154 | /* End PBXGroup section */
155 |
156 | /* Begin PBXNativeTarget section */
157 | 97C146ED1CF9000F007C117D /* Runner */ = {
158 | isa = PBXNativeTarget;
159 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
160 | buildPhases = (
161 | 060A4CDD59E2722244CFDD0E /* [CP] Check Pods Manifest.lock */,
162 | 9740EEB61CF901F6004384FC /* Run Script */,
163 | 97C146EA1CF9000F007C117D /* Sources */,
164 | 97C146EB1CF9000F007C117D /* Frameworks */,
165 | 97C146EC1CF9000F007C117D /* Resources */,
166 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
167 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
168 | 1C681DAA28B4269152958D4A /* [CP] Embed Pods Frameworks */,
169 | );
170 | buildRules = (
171 | );
172 | dependencies = (
173 | );
174 | name = Runner;
175 | productName = Runner;
176 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
177 | productType = "com.apple.product-type.application";
178 | };
179 | /* End PBXNativeTarget section */
180 |
181 | /* Begin PBXProject section */
182 | 97C146E61CF9000F007C117D /* Project object */ = {
183 | isa = PBXProject;
184 | attributes = {
185 | LastUpgradeCheck = 1020;
186 | ORGANIZATIONNAME = "The Chromium Authors";
187 | TargetAttributes = {
188 | 97C146ED1CF9000F007C117D = {
189 | CreatedOnToolsVersion = 7.3.1;
190 | LastSwiftMigration = 1120;
191 | };
192 | };
193 | };
194 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
195 | compatibilityVersion = "Xcode 3.2";
196 | developmentRegion = en;
197 | hasScannedForEncodings = 0;
198 | knownRegions = (
199 | en,
200 | Base,
201 | );
202 | mainGroup = 97C146E51CF9000F007C117D;
203 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
204 | projectDirPath = "";
205 | projectRoot = "";
206 | targets = (
207 | 97C146ED1CF9000F007C117D /* Runner */,
208 | );
209 | };
210 | /* End PBXProject section */
211 |
212 | /* Begin PBXResourcesBuildPhase section */
213 | 97C146EC1CF9000F007C117D /* Resources */ = {
214 | isa = PBXResourcesBuildPhase;
215 | buildActionMask = 2147483647;
216 | files = (
217 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
218 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
219 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
220 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
221 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | };
225 | /* End PBXResourcesBuildPhase section */
226 |
227 | /* Begin PBXShellScriptBuildPhase section */
228 | 060A4CDD59E2722244CFDD0E /* [CP] Check Pods Manifest.lock */ = {
229 | isa = PBXShellScriptBuildPhase;
230 | buildActionMask = 2147483647;
231 | files = (
232 | );
233 | inputFileListPaths = (
234 | );
235 | inputPaths = (
236 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
237 | "${PODS_ROOT}/Manifest.lock",
238 | );
239 | name = "[CP] Check Pods Manifest.lock";
240 | outputFileListPaths = (
241 | );
242 | outputPaths = (
243 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
244 | );
245 | runOnlyForDeploymentPostprocessing = 0;
246 | shellPath = /bin/sh;
247 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
248 | showEnvVarsInLog = 0;
249 | };
250 | 1C681DAA28B4269152958D4A /* [CP] Embed Pods Frameworks */ = {
251 | isa = PBXShellScriptBuildPhase;
252 | buildActionMask = 2147483647;
253 | files = (
254 | );
255 | inputPaths = (
256 | );
257 | name = "[CP] Embed Pods Frameworks";
258 | outputPaths = (
259 | );
260 | runOnlyForDeploymentPostprocessing = 0;
261 | shellPath = /bin/sh;
262 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
263 | showEnvVarsInLog = 0;
264 | };
265 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
266 | isa = PBXShellScriptBuildPhase;
267 | buildActionMask = 2147483647;
268 | files = (
269 | );
270 | inputPaths = (
271 | );
272 | name = "Thin Binary";
273 | outputPaths = (
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | shellPath = /bin/sh;
277 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
278 | };
279 | 9740EEB61CF901F6004384FC /* Run Script */ = {
280 | isa = PBXShellScriptBuildPhase;
281 | buildActionMask = 2147483647;
282 | files = (
283 | );
284 | inputPaths = (
285 | );
286 | name = "Run Script";
287 | outputPaths = (
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | shellPath = /bin/sh;
291 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
292 | };
293 | /* End PBXShellScriptBuildPhase section */
294 |
295 | /* Begin PBXSourcesBuildPhase section */
296 | 97C146EA1CF9000F007C117D /* Sources */ = {
297 | isa = PBXSourcesBuildPhase;
298 | buildActionMask = 2147483647;
299 | files = (
300 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
301 | 97C146F31CF9000F007C117D /* main.m in Sources */,
302 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
303 | );
304 | runOnlyForDeploymentPostprocessing = 0;
305 | };
306 | /* End PBXSourcesBuildPhase section */
307 |
308 | /* Begin PBXVariantGroup section */
309 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
310 | isa = PBXVariantGroup;
311 | children = (
312 | 97C146FB1CF9000F007C117D /* Base */,
313 | );
314 | name = Main.storyboard;
315 | sourceTree = "";
316 | };
317 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
318 | isa = PBXVariantGroup;
319 | children = (
320 | 97C147001CF9000F007C117D /* Base */,
321 | );
322 | name = LaunchScreen.storyboard;
323 | sourceTree = "";
324 | };
325 | /* End PBXVariantGroup section */
326 |
327 | /* Begin XCBuildConfiguration section */
328 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
329 | isa = XCBuildConfiguration;
330 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
331 | buildSettings = {
332 | ALWAYS_SEARCH_USER_PATHS = NO;
333 | CLANG_ANALYZER_NONNULL = YES;
334 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
335 | CLANG_CXX_LIBRARY = "libc++";
336 | CLANG_ENABLE_MODULES = YES;
337 | CLANG_ENABLE_OBJC_ARC = YES;
338 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
339 | CLANG_WARN_BOOL_CONVERSION = YES;
340 | CLANG_WARN_COMMA = YES;
341 | CLANG_WARN_CONSTANT_CONVERSION = YES;
342 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
343 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
344 | CLANG_WARN_EMPTY_BODY = YES;
345 | CLANG_WARN_ENUM_CONVERSION = YES;
346 | CLANG_WARN_INFINITE_RECURSION = YES;
347 | CLANG_WARN_INT_CONVERSION = YES;
348 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
349 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
350 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
351 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
352 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
353 | CLANG_WARN_STRICT_PROTOTYPES = YES;
354 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
355 | CLANG_WARN_UNREACHABLE_CODE = YES;
356 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
357 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
358 | COPY_PHASE_STRIP = NO;
359 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
360 | ENABLE_NS_ASSERTIONS = NO;
361 | ENABLE_STRICT_OBJC_MSGSEND = YES;
362 | GCC_C_LANGUAGE_STANDARD = gnu99;
363 | GCC_NO_COMMON_BLOCKS = YES;
364 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
365 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
366 | GCC_WARN_UNDECLARED_SELECTOR = YES;
367 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
368 | GCC_WARN_UNUSED_FUNCTION = YES;
369 | GCC_WARN_UNUSED_VARIABLE = YES;
370 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
371 | MTL_ENABLE_DEBUG_INFO = NO;
372 | SDKROOT = iphoneos;
373 | TARGETED_DEVICE_FAMILY = "1,2";
374 | VALIDATE_PRODUCT = YES;
375 | };
376 | name = Profile;
377 | };
378 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
379 | isa = XCBuildConfiguration;
380 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
381 | buildSettings = {
382 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
383 | CLANG_ENABLE_MODULES = YES;
384 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
385 | ENABLE_BITCODE = NO;
386 | FRAMEWORK_SEARCH_PATHS = (
387 | "$(inherited)",
388 | "$(PROJECT_DIR)/Flutter",
389 | );
390 | INFOPLIST_FILE = Runner/Info.plist;
391 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
392 | LIBRARY_SEARCH_PATHS = (
393 | "$(inherited)",
394 | "$(PROJECT_DIR)/Flutter",
395 | );
396 | PRODUCT_BUNDLE_IDENTIFIER = dev.com.jesway.example;
397 | PRODUCT_NAME = "$(TARGET_NAME)";
398 | SWIFT_OBJC_BRIDGING_HEADER = "Runner-Bridging-Header.h";
399 | SWIFT_VERSION = 5.0;
400 | VERSIONING_SYSTEM = "apple-generic";
401 | };
402 | name = Profile;
403 | };
404 | 97C147031CF9000F007C117D /* Debug */ = {
405 | isa = XCBuildConfiguration;
406 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
407 | buildSettings = {
408 | ALWAYS_SEARCH_USER_PATHS = NO;
409 | CLANG_ANALYZER_NONNULL = YES;
410 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
411 | CLANG_CXX_LIBRARY = "libc++";
412 | CLANG_ENABLE_MODULES = YES;
413 | CLANG_ENABLE_OBJC_ARC = YES;
414 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
415 | CLANG_WARN_BOOL_CONVERSION = YES;
416 | CLANG_WARN_COMMA = YES;
417 | CLANG_WARN_CONSTANT_CONVERSION = YES;
418 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
419 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
420 | CLANG_WARN_EMPTY_BODY = YES;
421 | CLANG_WARN_ENUM_CONVERSION = YES;
422 | CLANG_WARN_INFINITE_RECURSION = YES;
423 | CLANG_WARN_INT_CONVERSION = YES;
424 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
425 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
426 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
427 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
428 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
429 | CLANG_WARN_STRICT_PROTOTYPES = YES;
430 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
431 | CLANG_WARN_UNREACHABLE_CODE = YES;
432 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
433 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
434 | COPY_PHASE_STRIP = NO;
435 | DEBUG_INFORMATION_FORMAT = dwarf;
436 | ENABLE_STRICT_OBJC_MSGSEND = YES;
437 | ENABLE_TESTABILITY = YES;
438 | GCC_C_LANGUAGE_STANDARD = gnu99;
439 | GCC_DYNAMIC_NO_PIC = NO;
440 | GCC_NO_COMMON_BLOCKS = YES;
441 | GCC_OPTIMIZATION_LEVEL = 0;
442 | GCC_PREPROCESSOR_DEFINITIONS = (
443 | "DEBUG=1",
444 | "$(inherited)",
445 | );
446 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
447 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
448 | GCC_WARN_UNDECLARED_SELECTOR = YES;
449 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
450 | GCC_WARN_UNUSED_FUNCTION = YES;
451 | GCC_WARN_UNUSED_VARIABLE = YES;
452 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
453 | MTL_ENABLE_DEBUG_INFO = YES;
454 | ONLY_ACTIVE_ARCH = YES;
455 | SDKROOT = iphoneos;
456 | TARGETED_DEVICE_FAMILY = "1,2";
457 | };
458 | name = Debug;
459 | };
460 | 97C147041CF9000F007C117D /* Release */ = {
461 | isa = XCBuildConfiguration;
462 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
463 | buildSettings = {
464 | ALWAYS_SEARCH_USER_PATHS = NO;
465 | CLANG_ANALYZER_NONNULL = YES;
466 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
467 | CLANG_CXX_LIBRARY = "libc++";
468 | CLANG_ENABLE_MODULES = YES;
469 | CLANG_ENABLE_OBJC_ARC = YES;
470 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
471 | CLANG_WARN_BOOL_CONVERSION = YES;
472 | CLANG_WARN_COMMA = YES;
473 | CLANG_WARN_CONSTANT_CONVERSION = YES;
474 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
475 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
476 | CLANG_WARN_EMPTY_BODY = YES;
477 | CLANG_WARN_ENUM_CONVERSION = YES;
478 | CLANG_WARN_INFINITE_RECURSION = YES;
479 | CLANG_WARN_INT_CONVERSION = YES;
480 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
481 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
482 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
483 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
484 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
485 | CLANG_WARN_STRICT_PROTOTYPES = YES;
486 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
487 | CLANG_WARN_UNREACHABLE_CODE = YES;
488 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
489 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
490 | COPY_PHASE_STRIP = NO;
491 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
492 | ENABLE_NS_ASSERTIONS = NO;
493 | ENABLE_STRICT_OBJC_MSGSEND = YES;
494 | GCC_C_LANGUAGE_STANDARD = gnu99;
495 | GCC_NO_COMMON_BLOCKS = YES;
496 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
497 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
498 | GCC_WARN_UNDECLARED_SELECTOR = YES;
499 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
500 | GCC_WARN_UNUSED_FUNCTION = YES;
501 | GCC_WARN_UNUSED_VARIABLE = YES;
502 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
503 | MTL_ENABLE_DEBUG_INFO = NO;
504 | SDKROOT = iphoneos;
505 | TARGETED_DEVICE_FAMILY = "1,2";
506 | VALIDATE_PRODUCT = YES;
507 | };
508 | name = Release;
509 | };
510 | 97C147061CF9000F007C117D /* Debug */ = {
511 | isa = XCBuildConfiguration;
512 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
513 | buildSettings = {
514 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
515 | CLANG_ENABLE_MODULES = YES;
516 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
517 | ENABLE_BITCODE = NO;
518 | FRAMEWORK_SEARCH_PATHS = (
519 | "$(inherited)",
520 | "$(PROJECT_DIR)/Flutter",
521 | );
522 | INFOPLIST_FILE = Runner/Info.plist;
523 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
524 | LIBRARY_SEARCH_PATHS = (
525 | "$(inherited)",
526 | "$(PROJECT_DIR)/Flutter",
527 | );
528 | PRODUCT_BUNDLE_IDENTIFIER = dev.com.jesway.example;
529 | PRODUCT_NAME = "$(TARGET_NAME)";
530 | SWIFT_OBJC_BRIDGING_HEADER = "Runner-Bridging-Header.h";
531 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
532 | SWIFT_VERSION = 5.0;
533 | VERSIONING_SYSTEM = "apple-generic";
534 | };
535 | name = Debug;
536 | };
537 | 97C147071CF9000F007C117D /* Release */ = {
538 | isa = XCBuildConfiguration;
539 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
540 | buildSettings = {
541 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
542 | CLANG_ENABLE_MODULES = YES;
543 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
544 | ENABLE_BITCODE = NO;
545 | FRAMEWORK_SEARCH_PATHS = (
546 | "$(inherited)",
547 | "$(PROJECT_DIR)/Flutter",
548 | );
549 | INFOPLIST_FILE = Runner/Info.plist;
550 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
551 | LIBRARY_SEARCH_PATHS = (
552 | "$(inherited)",
553 | "$(PROJECT_DIR)/Flutter",
554 | );
555 | PRODUCT_BUNDLE_IDENTIFIER = dev.com.jesway.example;
556 | PRODUCT_NAME = "$(TARGET_NAME)";
557 | SWIFT_OBJC_BRIDGING_HEADER = "Runner-Bridging-Header.h";
558 | SWIFT_VERSION = 5.0;
559 | VERSIONING_SYSTEM = "apple-generic";
560 | };
561 | name = Release;
562 | };
563 | /* End XCBuildConfiguration section */
564 |
565 | /* Begin XCConfigurationList section */
566 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
567 | isa = XCConfigurationList;
568 | buildConfigurations = (
569 | 97C147031CF9000F007C117D /* Debug */,
570 | 97C147041CF9000F007C117D /* Release */,
571 | 249021D3217E4FDB00AE95B9 /* Profile */,
572 | );
573 | defaultConfigurationIsVisible = 0;
574 | defaultConfigurationName = Release;
575 | };
576 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
577 | isa = XCConfigurationList;
578 | buildConfigurations = (
579 | 97C147061CF9000F007C117D /* Debug */,
580 | 97C147071CF9000F007C117D /* Release */,
581 | 249021D4217E4FDB00AE95B9 /* Profile */,
582 | );
583 | defaultConfigurationIsVisible = 0;
584 | defaultConfigurationName = Release;
585 | };
586 | /* End XCConfigurationList section */
587 | };
588 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
589 | }
590 |
--------------------------------------------------------------------------------
/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 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/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/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_translate_example
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/example/ios/Runner/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 'package:flutter_localizations/flutter_localizations.dart';
2 | import 'package:flutter/cupertino.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_translate/flutter_translate.dart';
5 |
6 | void main() async
7 | {
8 | var delegate = await LocalizationDelegate.create(
9 | fallbackLocale: 'en_US',
10 | supportedLocales: ['en_US', 'es', 'fa', 'ar', 'ru']);
11 |
12 | runApp(LocalizedApp(delegate, MyApp()));
13 | }
14 |
15 | class MyApp extends StatelessWidget {
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 |
20 | var localizationDelegate = LocalizedApp.of(context).delegate;
21 |
22 | return LocalizationProvider(
23 | state: LocalizationProvider.of(context).state,
24 | child: MaterialApp(
25 | title: 'Flutter Translate Demo',
26 | localizationsDelegates: [
27 | GlobalMaterialLocalizations.delegate,
28 | GlobalWidgetsLocalizations.delegate,
29 | localizationDelegate
30 | ],
31 | supportedLocales: localizationDelegate.supportedLocales,
32 | locale: localizationDelegate.currentLocale,
33 | theme: ThemeData(primarySwatch: Colors.blue),
34 | home: MyHomePage(),
35 | ),
36 | );
37 | }
38 | }
39 |
40 | class MyHomePage extends StatefulWidget {
41 | MyHomePage({Key? key, this.title}) : super(key: key);
42 | final String? title;
43 |
44 | @override
45 | _MyHomePageState createState() => _MyHomePageState();
46 | }
47 |
48 | class _MyHomePageState extends State {
49 |
50 | int _counter = 0;
51 |
52 | void _decrementCounter() => setState(() => _counter--);
53 |
54 | void _incrementCounter() => setState(() => _counter++);
55 |
56 | @override
57 | Widget build(BuildContext context) {
58 | var localizationDelegate = LocalizedApp.of(context).delegate;
59 |
60 | return Scaffold(
61 | appBar: AppBar(
62 | title: Text(translate('app_bar.title')),
63 | ),
64 | body: Center(
65 | child: Column(
66 | mainAxisAlignment: MainAxisAlignment.center,
67 | children: [
68 | Text(translate('language.selected_message', args: {'language': translate('language.name.${localizationDelegate.currentLocale.languageCode}')})),
69 | Padding(
70 | padding: EdgeInsets.only(top: 25, bottom: 160),
71 | child: CupertinoButton.filled(
72 | child: Text(translate('button.change_language')),
73 | padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 36.0),
74 | onPressed: () => _onActionSheetPress(context),
75 | )
76 | ),
77 |
78 | Padding(padding: const EdgeInsets.only(bottom: 10),
79 | child: Text(translatePlural('plural.demo', _counter))
80 | ),
81 | Row(
82 | mainAxisAlignment: MainAxisAlignment.center,
83 | children: [
84 | IconButton(
85 | icon: Icon(Icons.remove_circle),
86 | iconSize: 48,
87 | onPressed: _counter > 0 ? () => setState(() => _decrementCounter()) : null,
88 | ),
89 | IconButton(
90 | icon: Icon(Icons.add_circle),
91 | color: Colors.blue,
92 | iconSize: 48,
93 | onPressed: () => setState(() => _incrementCounter()),
94 | ),
95 | ],
96 | )
97 |
98 | ],
99 | ),
100 | ),
101 | );
102 | }
103 |
104 | void showDemoActionSheet({required BuildContext context, required Widget child}) {
105 | showCupertinoModalPopup(
106 | context: context,
107 | builder: (BuildContext context) => child).then((String? value)
108 | {
109 | if(value != null)
110 | changeLocale(context, value);
111 | });
112 | }
113 |
114 | void _onActionSheetPress(BuildContext context) {
115 | showDemoActionSheet(
116 | context: context,
117 | child: CupertinoActionSheet(
118 | title: Text(translate('language.selection.title')),
119 | message: Text(translate('language.selection.message')),
120 | actions: [
121 | CupertinoActionSheetAction(
122 | child: Text(translate('language.name.en')),
123 | onPressed: () => Navigator.pop(context, 'en_US'),
124 | ),
125 | CupertinoActionSheetAction(
126 | child: Text(translate('language.name.es')),
127 | onPressed: () => Navigator.pop(context, 'es'),
128 | ),
129 | CupertinoActionSheetAction(
130 | child: Text(translate('language.name.ar')),
131 | onPressed: () => Navigator.pop(context, 'ar'),
132 | ),
133 | CupertinoActionSheetAction(
134 | child: Text(translate('language.name.ru')),
135 | onPressed: () => Navigator.pop(context, 'ru'),
136 | ),
137 | ],
138 | cancelButton: CupertinoActionSheetAction(
139 | child: Text(translate('button.cancel')),
140 | isDefaultAction: true,
141 | onPressed: () => Navigator.pop(context, null),
142 | ),
143 | ),
144 | );
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: example
2 | description: Example project for the flutter_translate library
3 | publish_to: none
4 | version: 4.1.0
5 |
6 | environment:
7 | sdk: '>=2.17.0 <4.0.0'
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | flutter_localizations:
13 | sdk: flutter
14 | flutter_translate:
15 | path: ../
16 |
17 | flutter:
18 |
19 | uses-material-design: true
20 | assets:
21 | - assets/i18n/
22 |
--------------------------------------------------------------------------------
/example/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/example/web/favicon.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/example/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/example/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/example/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | example
18 |
19 |
20 |
21 |
24 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "short_name": "example",
4 | "start_url": ".",
5 | "display": "minimal-ui",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/example/windows/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral/
2 |
3 | # Visual Studio user-specific files.
4 | *.suo
5 | *.user
6 | *.userosscache
7 | *.sln.docstates
8 |
9 | # Visual Studio build-related files.
10 | x64/
11 | x86/
12 |
13 | # Visual Studio cache files
14 | # files ending in .cache can be ignored
15 | *.[Cc]ache
16 | # but keep track of directories ending in .cache
17 | !*.[Cc]ache/
18 |
--------------------------------------------------------------------------------
/example/windows/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 | project(example LANGUAGES CXX)
3 |
4 | set(BINARY_NAME "example")
5 |
6 | cmake_policy(SET CMP0063 NEW)
7 |
8 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
9 |
10 | # Configure build options.
11 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
12 | if(IS_MULTICONFIG)
13 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
14 | CACHE STRING "" FORCE)
15 | else()
16 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
17 | set(CMAKE_BUILD_TYPE "Debug" CACHE
18 | STRING "Flutter build mode" FORCE)
19 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
20 | "Debug" "Profile" "Release")
21 | endif()
22 | endif()
23 |
24 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
25 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
26 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
27 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
28 |
29 | # Use Unicode for all projects.
30 | add_definitions(-DUNICODE -D_UNICODE)
31 |
32 | # Compilation settings that should be applied to most targets.
33 | function(APPLY_STANDARD_SETTINGS TARGET)
34 | target_compile_features(${TARGET} PUBLIC cxx_std_17)
35 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
36 | target_compile_options(${TARGET} PRIVATE /EHsc)
37 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
38 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>")
39 | endfunction()
40 |
41 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
42 |
43 | # Flutter library and tool build rules.
44 | add_subdirectory(${FLUTTER_MANAGED_DIR})
45 |
46 | # Application build
47 | add_subdirectory("runner")
48 |
49 | # Generated plugin build rules, which manage building the plugins and adding
50 | # them to the application.
51 | include(flutter/generated_plugins.cmake)
52 |
53 |
54 | # === Installation ===
55 | # Support files are copied into place next to the executable, so that it can
56 | # run in place. This is done instead of making a separate bundle (as on Linux)
57 | # so that building and running from within Visual Studio will work.
58 | set(BUILD_BUNDLE_DIR "$")
59 | # Make the "install" step default, as it's required to run.
60 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
61 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
62 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
63 | endif()
64 |
65 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
66 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
67 |
68 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
69 | COMPONENT Runtime)
70 |
71 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
72 | COMPONENT Runtime)
73 |
74 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
75 | COMPONENT Runtime)
76 |
77 | if(PLUGIN_BUNDLED_LIBRARIES)
78 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
79 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
80 | COMPONENT Runtime)
81 | endif()
82 |
83 | # Fully re-copy the assets directory on each build to avoid having stale files
84 | # from a previous install.
85 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
86 | install(CODE "
87 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
88 | " COMPONENT Runtime)
89 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
90 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
91 |
92 | # Install the AOT library on non-Debug builds only.
93 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
94 | CONFIGURATIONS Profile;Release
95 | COMPONENT Runtime)
96 |
--------------------------------------------------------------------------------
/example/windows/flutter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 |
3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
4 |
5 | # Configuration provided via flutter tool.
6 | include(${EPHEMERAL_DIR}/generated_config.cmake)
7 |
8 | # TODO: Move the rest of this into files in ephemeral. See
9 | # https://github.com/flutter/flutter/issues/57146.
10 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
11 |
12 | # Set fallback configurations for older versions of the flutter tool.
13 | if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
14 | set(FLUTTER_TARGET_PLATFORM "windows-x64")
15 | endif()
16 |
17 | # === Flutter Library ===
18 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
19 |
20 | # Published to parent scope for install step.
21 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
22 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
23 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
24 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
25 |
26 | list(APPEND FLUTTER_LIBRARY_HEADERS
27 | "flutter_export.h"
28 | "flutter_windows.h"
29 | "flutter_messenger.h"
30 | "flutter_plugin_registrar.h"
31 | "flutter_texture_registrar.h"
32 | )
33 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
34 | add_library(flutter INTERFACE)
35 | target_include_directories(flutter INTERFACE
36 | "${EPHEMERAL_DIR}"
37 | )
38 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
39 | add_dependencies(flutter flutter_assemble)
40 |
41 | # === Wrapper ===
42 | list(APPEND CPP_WRAPPER_SOURCES_CORE
43 | "core_implementations.cc"
44 | "standard_codec.cc"
45 | )
46 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
47 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
48 | "plugin_registrar.cc"
49 | )
50 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
51 | list(APPEND CPP_WRAPPER_SOURCES_APP
52 | "flutter_engine.cc"
53 | "flutter_view_controller.cc"
54 | )
55 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
56 |
57 | # Wrapper sources needed for a plugin.
58 | add_library(flutter_wrapper_plugin STATIC
59 | ${CPP_WRAPPER_SOURCES_CORE}
60 | ${CPP_WRAPPER_SOURCES_PLUGIN}
61 | )
62 | apply_standard_settings(flutter_wrapper_plugin)
63 | set_target_properties(flutter_wrapper_plugin PROPERTIES
64 | POSITION_INDEPENDENT_CODE ON)
65 | set_target_properties(flutter_wrapper_plugin PROPERTIES
66 | CXX_VISIBILITY_PRESET hidden)
67 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
68 | target_include_directories(flutter_wrapper_plugin PUBLIC
69 | "${WRAPPER_ROOT}/include"
70 | )
71 | add_dependencies(flutter_wrapper_plugin flutter_assemble)
72 |
73 | # Wrapper sources needed for the runner.
74 | add_library(flutter_wrapper_app STATIC
75 | ${CPP_WRAPPER_SOURCES_CORE}
76 | ${CPP_WRAPPER_SOURCES_APP}
77 | )
78 | apply_standard_settings(flutter_wrapper_app)
79 | target_link_libraries(flutter_wrapper_app PUBLIC flutter)
80 | target_include_directories(flutter_wrapper_app PUBLIC
81 | "${WRAPPER_ROOT}/include"
82 | )
83 | add_dependencies(flutter_wrapper_app flutter_assemble)
84 |
85 | # === Flutter tool backend ===
86 | # _phony_ is a non-existent file to force this command to run every time,
87 | # since currently there's no way to get a full input/output list from the
88 | # flutter tool.
89 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
90 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
91 | add_custom_command(
92 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
93 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
94 | ${CPP_WRAPPER_SOURCES_APP}
95 | ${PHONY_OUTPUT}
96 | COMMAND ${CMAKE_COMMAND} -E env
97 | ${FLUTTER_TOOL_ENVIRONMENT}
98 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
99 | ${FLUTTER_TARGET_PLATFORM} $
100 | VERBATIM
101 | )
102 | add_custom_target(flutter_assemble DEPENDS
103 | "${FLUTTER_LIBRARY}"
104 | ${FLUTTER_LIBRARY_HEADERS}
105 | ${CPP_WRAPPER_SOURCES_CORE}
106 | ${CPP_WRAPPER_SOURCES_PLUGIN}
107 | ${CPP_WRAPPER_SOURCES_APP}
108 | )
109 |
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #include "generated_plugin_registrant.h"
8 |
9 |
10 | void RegisterPlugins(flutter::PluginRegistry* registry) {
11 | }
12 |
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #ifndef GENERATED_PLUGIN_REGISTRANT_
8 | #define GENERATED_PLUGIN_REGISTRANT_
9 |
10 | #include
11 |
12 | // Registers Flutter plugins.
13 | void RegisterPlugins(flutter::PluginRegistry* registry);
14 |
15 | #endif // GENERATED_PLUGIN_REGISTRANT_
16 |
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | )
7 |
8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST
9 | )
10 |
11 | set(PLUGIN_BUNDLED_LIBRARIES)
12 |
13 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
18 | endforeach(plugin)
19 |
20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
23 | endforeach(ffi_plugin)
24 |
--------------------------------------------------------------------------------
/example/windows/runner/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 | project(runner LANGUAGES CXX)
3 |
4 | add_executable(${BINARY_NAME} WIN32
5 | "flutter_window.cpp"
6 | "main.cpp"
7 | "run_loop.cpp"
8 | "utils.cpp"
9 | "win32_window.cpp"
10 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
11 | "Runner.rc"
12 | "runner.exe.manifest"
13 | )
14 | apply_standard_settings(${BINARY_NAME})
15 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
16 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
17 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
18 | add_dependencies(${BINARY_NAME} flutter_assemble)
19 |
--------------------------------------------------------------------------------
/example/windows/runner/Runner.rc:
--------------------------------------------------------------------------------
1 | // Microsoft Visual C++ generated resource script.
2 | //
3 | #pragma code_page(65001)
4 | #include "resource.h"
5 |
6 | #define APSTUDIO_READONLY_SYMBOLS
7 | /////////////////////////////////////////////////////////////////////////////
8 | //
9 | // Generated from the TEXTINCLUDE 2 resource.
10 | //
11 | #include "winres.h"
12 |
13 | /////////////////////////////////////////////////////////////////////////////
14 | #undef APSTUDIO_READONLY_SYMBOLS
15 |
16 | /////////////////////////////////////////////////////////////////////////////
17 | // English (United States) resources
18 |
19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
21 |
22 | #ifdef APSTUDIO_INVOKED
23 | /////////////////////////////////////////////////////////////////////////////
24 | //
25 | // TEXTINCLUDE
26 | //
27 |
28 | 1 TEXTINCLUDE
29 | BEGIN
30 | "resource.h\0"
31 | END
32 |
33 | 2 TEXTINCLUDE
34 | BEGIN
35 | "#include ""winres.h""\r\n"
36 | "\0"
37 | END
38 |
39 | 3 TEXTINCLUDE
40 | BEGIN
41 | "\r\n"
42 | "\0"
43 | END
44 |
45 | #endif // APSTUDIO_INVOKED
46 |
47 |
48 | /////////////////////////////////////////////////////////////////////////////
49 | //
50 | // Icon
51 | //
52 |
53 | // Icon with lowest ID value placed first to ensure application icon
54 | // remains consistent on all systems.
55 | IDI_APP_ICON ICON "resources\\app_icon.ico"
56 |
57 |
58 | /////////////////////////////////////////////////////////////////////////////
59 | //
60 | // Version
61 | //
62 |
63 | #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
64 | #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
65 | #else
66 | #define VERSION_AS_NUMBER 1,0,0,0
67 | #endif
68 |
69 | #if defined(FLUTTER_VERSION)
70 | #define VERSION_AS_STRING FLUTTER_VERSION
71 | #else
72 | #define VERSION_AS_STRING "1.0.0"
73 | #endif
74 |
75 | VS_VERSION_INFO VERSIONINFO
76 | FILEVERSION VERSION_AS_NUMBER
77 | PRODUCTVERSION VERSION_AS_NUMBER
78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
79 | #ifdef _DEBUG
80 | FILEFLAGS VS_FF_DEBUG
81 | #else
82 | FILEFLAGS 0x0L
83 | #endif
84 | FILEOS VOS__WINDOWS32
85 | FILETYPE VFT_APP
86 | FILESUBTYPE 0x0L
87 | BEGIN
88 | BLOCK "StringFileInfo"
89 | BEGIN
90 | BLOCK "040904e4"
91 | BEGIN
92 | VALUE "CompanyName", "Jesway Labs" "\0"
93 | VALUE "FileDescription", "A new Flutter project." "\0"
94 | VALUE "FileVersion", VERSION_AS_STRING "\0"
95 | VALUE "InternalName", "example" "\0"
96 | VALUE "LegalCopyright", "Copyright (C) 2021 Jesway Labs. All rights reserved." "\0"
97 | VALUE "OriginalFilename", "example.exe" "\0"
98 | VALUE "ProductName", "example" "\0"
99 | VALUE "ProductVersion", VERSION_AS_STRING "\0"
100 | END
101 | END
102 | BLOCK "VarFileInfo"
103 | BEGIN
104 | VALUE "Translation", 0x409, 1252
105 | END
106 | END
107 |
108 | #endif // English (United States) resources
109 | /////////////////////////////////////////////////////////////////////////////
110 |
111 |
112 |
113 | #ifndef APSTUDIO_INVOKED
114 | /////////////////////////////////////////////////////////////////////////////
115 | //
116 | // Generated from the TEXTINCLUDE 3 resource.
117 | //
118 |
119 |
120 | /////////////////////////////////////////////////////////////////////////////
121 | #endif // not APSTUDIO_INVOKED
122 |
--------------------------------------------------------------------------------
/example/windows/runner/flutter_window.cpp:
--------------------------------------------------------------------------------
1 | #include "flutter_window.h"
2 |
3 | #include
4 |
5 | #include "flutter/generated_plugin_registrant.h"
6 |
7 | FlutterWindow::FlutterWindow(RunLoop* run_loop,
8 | const flutter::DartProject& project)
9 | : run_loop_(run_loop), project_(project) {}
10 |
11 | FlutterWindow::~FlutterWindow() {}
12 |
13 | bool FlutterWindow::OnCreate() {
14 | if (!Win32Window::OnCreate()) {
15 | return false;
16 | }
17 |
18 | RECT frame = GetClientArea();
19 |
20 | // The size here must match the window dimensions to avoid unnecessary surface
21 | // creation / destruction in the startup path.
22 | flutter_controller_ = std::make_unique(
23 | frame.right - frame.left, frame.bottom - frame.top, project_);
24 | // Ensure that basic setup of the controller was successful.
25 | if (!flutter_controller_->engine() || !flutter_controller_->view()) {
26 | return false;
27 | }
28 | RegisterPlugins(flutter_controller_->engine());
29 | run_loop_->RegisterFlutterInstance(flutter_controller_->engine());
30 | SetChildContent(flutter_controller_->view()->GetNativeWindow());
31 | return true;
32 | }
33 |
34 | void FlutterWindow::OnDestroy() {
35 | if (flutter_controller_) {
36 | run_loop_->UnregisterFlutterInstance(flutter_controller_->engine());
37 | flutter_controller_ = nullptr;
38 | }
39 |
40 | Win32Window::OnDestroy();
41 | }
42 |
43 | LRESULT
44 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
45 | WPARAM const wparam,
46 | LPARAM const lparam) noexcept {
47 | // Give Flutter, including plugins, an opportunity to handle window messages.
48 | if (flutter_controller_) {
49 | std::optional result =
50 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
51 | lparam);
52 | if (result) {
53 | return *result;
54 | }
55 | }
56 |
57 | switch (message) {
58 | case WM_FONTCHANGE:
59 | flutter_controller_->engine()->ReloadSystemFonts();
60 | break;
61 | }
62 |
63 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
64 | }
65 |
--------------------------------------------------------------------------------
/example/windows/runner/flutter_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_FLUTTER_WINDOW_H_
2 | #define RUNNER_FLUTTER_WINDOW_H_
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | #include "run_loop.h"
10 | #include "win32_window.h"
11 |
12 | // A window that does nothing but host a Flutter view.
13 | class FlutterWindow : public Win32Window {
14 | public:
15 | // Creates a new FlutterWindow driven by the |run_loop|, hosting a
16 | // Flutter view running |project|.
17 | explicit FlutterWindow(RunLoop* run_loop,
18 | const flutter::DartProject& project);
19 | virtual ~FlutterWindow();
20 |
21 | protected:
22 | // Win32Window:
23 | bool OnCreate() override;
24 | void OnDestroy() override;
25 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
26 | LPARAM const lparam) noexcept override;
27 |
28 | private:
29 | // The run loop driving events for this window.
30 | RunLoop* run_loop_;
31 |
32 | // The project to run.
33 | flutter::DartProject project_;
34 |
35 | // The Flutter instance hosted by this window.
36 | std::unique_ptr flutter_controller_;
37 | };
38 |
39 | #endif // RUNNER_FLUTTER_WINDOW_H_
40 |
--------------------------------------------------------------------------------
/example/windows/runner/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "flutter_window.h"
6 | #include "run_loop.h"
7 | #include "utils.h"
8 |
9 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
10 | _In_ wchar_t *command_line, _In_ int show_command) {
11 | // Attach to console when present (e.g., 'flutter run') or create a
12 | // new console when running with a debugger.
13 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
14 | CreateAndAttachConsole();
15 | }
16 |
17 | // Initialize COM, so that it is available for use in the library and/or
18 | // plugins.
19 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
20 |
21 | RunLoop run_loop;
22 |
23 | flutter::DartProject project(L"data");
24 |
25 | std::vector command_line_arguments =
26 | GetCommandLineArguments();
27 |
28 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
29 |
30 | FlutterWindow window(&run_loop, project);
31 | Win32Window::Point origin(10, 10);
32 | Win32Window::Size size(1280, 720);
33 | if (!window.CreateAndShow(L"example", origin, size)) {
34 | return EXIT_FAILURE;
35 | }
36 | window.SetQuitOnClose(true);
37 |
38 | run_loop.Run();
39 |
40 | ::CoUninitialize();
41 | return EXIT_SUCCESS;
42 | }
43 |
--------------------------------------------------------------------------------
/example/windows/runner/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Runner.rc
4 | //
5 | #define IDI_APP_ICON 101
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NEXT_RESOURCE_VALUE 102
12 | #define _APS_NEXT_COMMAND_VALUE 40001
13 | #define _APS_NEXT_CONTROL_VALUE 1001
14 | #define _APS_NEXT_SYMED_VALUE 101
15 | #endif
16 | #endif
17 |
--------------------------------------------------------------------------------
/example/windows/runner/resources/app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jesway/flutter_translate/c4e46902ecf15a2746e3ed07f2a7c5ecf1b8b833/example/windows/runner/resources/app_icon.ico
--------------------------------------------------------------------------------
/example/windows/runner/run_loop.cpp:
--------------------------------------------------------------------------------
1 | #include "run_loop.h"
2 |
3 | #include
4 |
5 | #include
6 |
7 | RunLoop::RunLoop() {}
8 |
9 | RunLoop::~RunLoop() {}
10 |
11 | void RunLoop::Run() {
12 | bool keep_running = true;
13 | TimePoint next_flutter_event_time = TimePoint::clock::now();
14 | while (keep_running) {
15 | std::chrono::nanoseconds wait_duration =
16 | std::max(std::chrono::nanoseconds(0),
17 | next_flutter_event_time - TimePoint::clock::now());
18 | ::MsgWaitForMultipleObjects(
19 | 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000),
20 | QS_ALLINPUT);
21 | bool processed_events = false;
22 | MSG message;
23 | // All pending Windows messages must be processed; MsgWaitForMultipleObjects
24 | // won't return again for items left in the queue after PeekMessage.
25 | while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) {
26 | processed_events = true;
27 | if (message.message == WM_QUIT) {
28 | keep_running = false;
29 | break;
30 | }
31 | ::TranslateMessage(&message);
32 | ::DispatchMessage(&message);
33 | // Allow Flutter to process messages each time a Windows message is
34 | // processed, to prevent starvation.
35 | next_flutter_event_time =
36 | std::min(next_flutter_event_time, ProcessFlutterMessages());
37 | }
38 | // If the PeekMessage loop didn't run, process Flutter messages.
39 | if (!processed_events) {
40 | next_flutter_event_time =
41 | std::min(next_flutter_event_time, ProcessFlutterMessages());
42 | }
43 | }
44 | }
45 |
46 | void RunLoop::RegisterFlutterInstance(
47 | flutter::FlutterEngine* flutter_instance) {
48 | flutter_instances_.insert(flutter_instance);
49 | }
50 |
51 | void RunLoop::UnregisterFlutterInstance(
52 | flutter::FlutterEngine* flutter_instance) {
53 | flutter_instances_.erase(flutter_instance);
54 | }
55 |
56 | RunLoop::TimePoint RunLoop::ProcessFlutterMessages() {
57 | TimePoint next_event_time = TimePoint::max();
58 | for (auto instance : flutter_instances_) {
59 | std::chrono::nanoseconds wait_duration = instance->ProcessMessages();
60 | if (wait_duration != std::chrono::nanoseconds::max()) {
61 | next_event_time =
62 | std::min(next_event_time, TimePoint::clock::now() + wait_duration);
63 | }
64 | }
65 | return next_event_time;
66 | }
67 |
--------------------------------------------------------------------------------
/example/windows/runner/run_loop.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_RUN_LOOP_H_
2 | #define RUNNER_RUN_LOOP_H_
3 |
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | // A runloop that will service events for Flutter instances as well
10 | // as native messages.
11 | class RunLoop {
12 | public:
13 | RunLoop();
14 | ~RunLoop();
15 |
16 | // Prevent copying
17 | RunLoop(RunLoop const&) = delete;
18 | RunLoop& operator=(RunLoop const&) = delete;
19 |
20 | // Runs the run loop until the application quits.
21 | void Run();
22 |
23 | // Registers the given Flutter instance for event servicing.
24 | void RegisterFlutterInstance(
25 | flutter::FlutterEngine* flutter_instance);
26 |
27 | // Unregisters the given Flutter instance from event servicing.
28 | void UnregisterFlutterInstance(
29 | flutter::FlutterEngine* flutter_instance);
30 |
31 | private:
32 | using TimePoint = std::chrono::steady_clock::time_point;
33 |
34 | // Processes all currently pending messages for registered Flutter instances.
35 | TimePoint ProcessFlutterMessages();
36 |
37 | std::set flutter_instances_;
38 | };
39 |
40 | #endif // RUNNER_RUN_LOOP_H_
41 |
--------------------------------------------------------------------------------
/example/windows/runner/runner.exe.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PerMonitorV2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/example/windows/runner/utils.cpp:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | void CreateAndAttachConsole() {
11 | if (::AllocConsole()) {
12 | FILE *unused;
13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
14 | _dup2(_fileno(stdout), 1);
15 | }
16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
17 | _dup2(_fileno(stdout), 2);
18 | }
19 | std::ios::sync_with_stdio();
20 | FlutterDesktopResyncOutputStreams();
21 | }
22 | }
23 |
24 | std::vector GetCommandLineArguments() {
25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
26 | int argc;
27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
28 | if (argv == nullptr) {
29 | return std::vector();
30 | }
31 |
32 | std::vector command_line_arguments;
33 |
34 | // Skip the first argument as it's the binary name.
35 | for (int i = 1; i < argc; i++) {
36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
37 | }
38 |
39 | ::LocalFree(argv);
40 |
41 | return command_line_arguments;
42 | }
43 |
44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
45 | if (utf16_string == nullptr) {
46 | return std::string();
47 | }
48 | int target_length = ::WideCharToMultiByte(
49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
50 | -1, nullptr, 0, nullptr, nullptr);
51 | if (target_length == 0) {
52 | return std::string();
53 | }
54 | std::string utf8_string;
55 | utf8_string.resize(target_length);
56 | int converted_length = ::WideCharToMultiByte(
57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
58 | -1, utf8_string.data(),
59 | target_length, nullptr, nullptr);
60 | if (converted_length == 0) {
61 | return std::string();
62 | }
63 | return utf8_string;
64 | }
65 |
--------------------------------------------------------------------------------
/example/windows/runner/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_UTILS_H_
2 | #define RUNNER_UTILS_H_
3 |
4 | #include
5 | #include
6 |
7 | // Creates a console for the process, and redirects stdout and stderr to
8 | // it for both the runner and the Flutter library.
9 | void CreateAndAttachConsole();
10 |
11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
12 | // encoded in UTF-8. Returns an empty std::string on failure.
13 | std::string Utf8FromUtf16(const wchar_t* utf16_string);
14 |
15 | // Gets the command line arguments passed in as a std::vector,
16 | // encoded in UTF-8. Returns an empty std::vector on failure.
17 | std::vector GetCommandLineArguments();
18 |
19 | #endif // RUNNER_UTILS_H_
20 |
--------------------------------------------------------------------------------
/example/windows/runner/win32_window.cpp:
--------------------------------------------------------------------------------
1 | #include "win32_window.h"
2 |
3 | #include
4 |
5 | #include "resource.h"
6 |
7 | namespace {
8 |
9 | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
10 |
11 | // The number of Win32Window objects that currently exist.
12 | static int g_active_window_count = 0;
13 |
14 | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
15 |
16 | // Scale helper to convert logical scaler values to physical using passed in
17 | // scale factor
18 | int Scale(int source, double scale_factor) {
19 | return static_cast(source * scale_factor);
20 | }
21 |
22 | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
23 | // This API is only needed for PerMonitor V1 awareness mode.
24 | void EnableFullDpiSupportIfAvailable(HWND hwnd) {
25 | HMODULE user32_module = LoadLibraryA("User32.dll");
26 | if (!user32_module) {
27 | return;
28 | }
29 | auto enable_non_client_dpi_scaling =
30 | reinterpret_cast(
31 | GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
32 | if (enable_non_client_dpi_scaling != nullptr) {
33 | enable_non_client_dpi_scaling(hwnd);
34 | FreeLibrary(user32_module);
35 | }
36 | }
37 |
38 | } // namespace
39 |
40 | // Manages the Win32Window's window class registration.
41 | class WindowClassRegistrar {
42 | public:
43 | ~WindowClassRegistrar() = default;
44 |
45 | // Returns the singleton registar instance.
46 | static WindowClassRegistrar* GetInstance() {
47 | if (!instance_) {
48 | instance_ = new WindowClassRegistrar();
49 | }
50 | return instance_;
51 | }
52 |
53 | // Returns the name of the window class, registering the class if it hasn't
54 | // previously been registered.
55 | const wchar_t* GetWindowClass();
56 |
57 | // Unregisters the window class. Should only be called if there are no
58 | // instances of the window.
59 | void UnregisterWindowClass();
60 |
61 | private:
62 | WindowClassRegistrar() = default;
63 |
64 | static WindowClassRegistrar* instance_;
65 |
66 | bool class_registered_ = false;
67 | };
68 |
69 | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
70 |
71 | const wchar_t* WindowClassRegistrar::GetWindowClass() {
72 | if (!class_registered_) {
73 | WNDCLASS window_class{};
74 | window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
75 | window_class.lpszClassName = kWindowClassName;
76 | window_class.style = CS_HREDRAW | CS_VREDRAW;
77 | window_class.cbClsExtra = 0;
78 | window_class.cbWndExtra = 0;
79 | window_class.hInstance = GetModuleHandle(nullptr);
80 | window_class.hIcon =
81 | LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
82 | window_class.hbrBackground = 0;
83 | window_class.lpszMenuName = nullptr;
84 | window_class.lpfnWndProc = Win32Window::WndProc;
85 | RegisterClass(&window_class);
86 | class_registered_ = true;
87 | }
88 | return kWindowClassName;
89 | }
90 |
91 | void WindowClassRegistrar::UnregisterWindowClass() {
92 | UnregisterClass(kWindowClassName, nullptr);
93 | class_registered_ = false;
94 | }
95 |
96 | Win32Window::Win32Window() {
97 | ++g_active_window_count;
98 | }
99 |
100 | Win32Window::~Win32Window() {
101 | --g_active_window_count;
102 | Destroy();
103 | }
104 |
105 | bool Win32Window::CreateAndShow(const std::wstring& title,
106 | const Point& origin,
107 | const Size& size) {
108 | Destroy();
109 |
110 | const wchar_t* window_class =
111 | WindowClassRegistrar::GetInstance()->GetWindowClass();
112 |
113 | const POINT target_point = {static_cast(origin.x),
114 | static_cast(origin.y)};
115 | HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
116 | UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
117 | double scale_factor = dpi / 96.0;
118 |
119 | HWND window = CreateWindow(
120 | window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
121 | Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
122 | Scale(size.width, scale_factor), Scale(size.height, scale_factor),
123 | nullptr, nullptr, GetModuleHandle(nullptr), this);
124 |
125 | if (!window) {
126 | return false;
127 | }
128 |
129 | return OnCreate();
130 | }
131 |
132 | // static
133 | LRESULT CALLBACK Win32Window::WndProc(HWND const window,
134 | UINT const message,
135 | WPARAM const wparam,
136 | LPARAM const lparam) noexcept {
137 | if (message == WM_NCCREATE) {
138 | auto window_struct = reinterpret_cast(lparam);
139 | SetWindowLongPtr(window, GWLP_USERDATA,
140 | reinterpret_cast(window_struct->lpCreateParams));
141 |
142 | auto that = static_cast(window_struct->lpCreateParams);
143 | EnableFullDpiSupportIfAvailable(window);
144 | that->window_handle_ = window;
145 | } else if (Win32Window* that = GetThisFromHandle(window)) {
146 | return that->MessageHandler(window, message, wparam, lparam);
147 | }
148 |
149 | return DefWindowProc(window, message, wparam, lparam);
150 | }
151 |
152 | LRESULT
153 | Win32Window::MessageHandler(HWND hwnd,
154 | UINT const message,
155 | WPARAM const wparam,
156 | LPARAM const lparam) noexcept {
157 | switch (message) {
158 | case WM_DESTROY:
159 | window_handle_ = nullptr;
160 | Destroy();
161 | if (quit_on_close_) {
162 | PostQuitMessage(0);
163 | }
164 | return 0;
165 |
166 | case WM_DPICHANGED: {
167 | auto newRectSize = reinterpret_cast(lparam);
168 | LONG newWidth = newRectSize->right - newRectSize->left;
169 | LONG newHeight = newRectSize->bottom - newRectSize->top;
170 |
171 | SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
172 | newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
173 |
174 | return 0;
175 | }
176 | case WM_SIZE: {
177 | RECT rect = GetClientArea();
178 | if (child_content_ != nullptr) {
179 | // Size and position the child window.
180 | MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
181 | rect.bottom - rect.top, TRUE);
182 | }
183 | return 0;
184 | }
185 |
186 | case WM_ACTIVATE:
187 | if (child_content_ != nullptr) {
188 | SetFocus(child_content_);
189 | }
190 | return 0;
191 | }
192 |
193 | return DefWindowProc(window_handle_, message, wparam, lparam);
194 | }
195 |
196 | void Win32Window::Destroy() {
197 | OnDestroy();
198 |
199 | if (window_handle_) {
200 | DestroyWindow(window_handle_);
201 | window_handle_ = nullptr;
202 | }
203 | if (g_active_window_count == 0) {
204 | WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
205 | }
206 | }
207 |
208 | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
209 | return reinterpret_cast(
210 | GetWindowLongPtr(window, GWLP_USERDATA));
211 | }
212 |
213 | void Win32Window::SetChildContent(HWND content) {
214 | child_content_ = content;
215 | SetParent(content, window_handle_);
216 | RECT frame = GetClientArea();
217 |
218 | MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
219 | frame.bottom - frame.top, true);
220 |
221 | SetFocus(child_content_);
222 | }
223 |
224 | RECT Win32Window::GetClientArea() {
225 | RECT frame;
226 | GetClientRect(window_handle_, &frame);
227 | return frame;
228 | }
229 |
230 | HWND Win32Window::GetHandle() {
231 | return window_handle_;
232 | }
233 |
234 | void Win32Window::SetQuitOnClose(bool quit_on_close) {
235 | quit_on_close_ = quit_on_close;
236 | }
237 |
238 | bool Win32Window::OnCreate() {
239 | // No-op; provided for subclasses.
240 | return true;
241 | }
242 |
243 | void Win32Window::OnDestroy() {
244 | // No-op; provided for subclasses.
245 | }
246 |
--------------------------------------------------------------------------------
/example/windows/runner/win32_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_WIN32_WINDOW_H_
2 | #define RUNNER_WIN32_WINDOW_H_
3 |
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be
11 | // inherited from by classes that wish to specialize with custom
12 | // rendering and input handling
13 | class Win32Window {
14 | public:
15 | struct Point {
16 | unsigned int x;
17 | unsigned int y;
18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {}
19 | };
20 |
21 | struct Size {
22 | unsigned int width;
23 | unsigned int height;
24 | Size(unsigned int width, unsigned int height)
25 | : width(width), height(height) {}
26 | };
27 |
28 | Win32Window();
29 | virtual ~Win32Window();
30 |
31 | // Creates and shows a win32 window with |title| and position and size using
32 | // |origin| and |size|. New windows are created on the default monitor. Window
33 | // sizes are specified to the OS in physical pixels, hence to ensure a
34 | // consistent size to will treat the width height passed in to this function
35 | // as logical pixels and scale to appropriate for the default monitor. Returns
36 | // true if the window was created successfully.
37 | bool CreateAndShow(const std::wstring& title,
38 | const Point& origin,
39 | const Size& size);
40 |
41 | // Release OS resources associated with window.
42 | void Destroy();
43 |
44 | // Inserts |content| into the window tree.
45 | void SetChildContent(HWND content);
46 |
47 | // Returns the backing Window handle to enable clients to set icon and other
48 | // window properties. Returns nullptr if the window has been destroyed.
49 | HWND GetHandle();
50 |
51 | // If true, closing this window will quit the application.
52 | void SetQuitOnClose(bool quit_on_close);
53 |
54 | // Return a RECT representing the bounds of the current client area.
55 | RECT GetClientArea();
56 |
57 | protected:
58 | // Processes and route salient window messages for mouse handling,
59 | // size change and DPI. Delegates handling of these to member overloads that
60 | // inheriting classes can handle.
61 | virtual LRESULT MessageHandler(HWND window,
62 | UINT const message,
63 | WPARAM const wparam,
64 | LPARAM const lparam) noexcept;
65 |
66 | // Called when CreateAndShow is called, allowing subclass window-related
67 | // setup. Subclasses should return false if setup fails.
68 | virtual bool OnCreate();
69 |
70 | // Called when Destroy is called.
71 | virtual void OnDestroy();
72 |
73 | private:
74 | friend class WindowClassRegistrar;
75 |
76 | // OS callback called by message pump. Handles the WM_NCCREATE message which
77 | // is passed when the non-client area is being created and enables automatic
78 | // non-client DPI scaling so that the non-client area automatically
79 | // responsponds to changes in DPI. All other messages are handled by
80 | // MessageHandler.
81 | static LRESULT CALLBACK WndProc(HWND const window,
82 | UINT const message,
83 | WPARAM const wparam,
84 | LPARAM const lparam) noexcept;
85 |
86 | // Retrieves a class instance pointer for |window|
87 | static Win32Window* GetThisFromHandle(HWND const window) noexcept;
88 |
89 | bool quit_on_close_ = false;
90 |
91 | // window handle for top level window.
92 | HWND window_handle_ = nullptr;
93 |
94 | // window handle for hosted content.
95 | HWND child_content_ = nullptr;
96 | };
97 |
98 | #endif // RUNNER_WIN32_WINDOW_H_
99 |
--------------------------------------------------------------------------------
/lib/flutter_translate.dart:
--------------------------------------------------------------------------------
1 | library flutter_translate;
2 |
3 | export 'src/utils/utils.dart';
4 | export 'src/services/localization.dart';
5 | export 'src/delegates/localization_delegate.dart';
6 | export 'src/widgets/localization_provider.dart';
7 | export 'src/widgets/localized_app.dart';
8 | export 'src/widgets/localized_app_state.dart';
9 | export 'src/interfaces/translate_preferences.dart';
10 | export 'src/utils/device_locale.dart';
--------------------------------------------------------------------------------
/lib/src/constants/constants.dart:
--------------------------------------------------------------------------------
1 | class Constants
2 | {
3 | static const String assetManifestFilename = 'AssetManifest.json';
4 |
5 | static const String localizedAssetsPath = 'assets/i18n';
6 |
7 | static const String pluralZero = 'zero';
8 | static const String pluralOne = 'one';
9 | static const String pluralTwo = 'two';
10 | static const String pluralFew = 'few';
11 | static const String pluralMany = 'many';
12 | static const String pluralOther = 'other';
13 |
14 | static const String pluralValueArg = '{{value}}';
15 | }
--------------------------------------------------------------------------------
/lib/src/delegates/localization_delegate.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:intl/intl.dart';
3 | import 'package:flutter_translate/flutter_translate.dart';
4 | import 'package:flutter_translate/src/constants/constants.dart';
5 | import 'package:flutter_translate/src/services/locale_service.dart';
6 | import 'package:flutter_translate/src/validators/configuration_validator.dart';
7 |
8 | class LocalizationDelegate extends LocalizationsDelegate
9 | {
10 | Locale? _currentLocale;
11 |
12 | final Locale fallbackLocale;
13 |
14 | final List supportedLocales;
15 |
16 | final Map supportedLocalesMap;
17 |
18 | final ITranslatePreferences? preferences;
19 |
20 | LocaleChangedCallback? onLocaleChanged;
21 |
22 | Locale get currentLocale => _currentLocale!;
23 |
24 | LocalizationDelegate._(this.fallbackLocale, this.supportedLocales, this.supportedLocalesMap, this.preferences);
25 |
26 | Future changeLocale(Locale newLocale) async
27 | {
28 | var isInitializing = _currentLocale == null;
29 |
30 | var locale = LocaleService.findLocale(newLocale, supportedLocales) ?? fallbackLocale;
31 |
32 | if(_currentLocale == locale) return;
33 |
34 | var localizedContent = await LocaleService.getLocaleContent(locale, supportedLocalesMap);
35 |
36 | Localization.load(localizedContent);
37 |
38 | _currentLocale = locale;
39 |
40 | Intl.defaultLocale = _currentLocale?.languageCode;
41 |
42 | if(onLocaleChanged != null)
43 | {
44 | await onLocaleChanged!(locale);
45 | }
46 |
47 | if(!isInitializing && preferences != null)
48 | {
49 | await preferences!.savePreferredLocale(locale);
50 | }
51 | }
52 |
53 | @override
54 | Future load(Locale newLocale) async
55 | {
56 | if(currentLocale != newLocale)
57 | {
58 | await changeLocale(newLocale);
59 | }
60 |
61 | return Localization.instance;
62 | }
63 |
64 |
65 | @override
66 | bool isSupported(Locale? locale) => locale != null;
67 |
68 | @override
69 | bool shouldReload(LocalizationsDelegate old) => true;
70 |
71 | static Future create({
72 | required String fallbackLocale,
73 | required List supportedLocales,
74 | String basePath = Constants.localizedAssetsPath,
75 | ITranslatePreferences? preferences}) async
76 | {
77 | WidgetsFlutterBinding.ensureInitialized();
78 |
79 | var fallback = localeFromString(fallbackLocale);
80 | var localesMap = await LocaleService.getLocalesMap(supportedLocales, basePath);
81 | var locales = localesMap.keys.toList();
82 |
83 | ConfigurationValidator.validate(fallback, locales);
84 |
85 | var delegate = LocalizationDelegate._(fallback, locales, localesMap, preferences);
86 |
87 | if(!await delegate._loadPreferences())
88 | {
89 | await delegate._loadDeviceLocale();
90 | }
91 |
92 | return delegate;
93 | }
94 |
95 | Future _loadPreferences() async
96 | {
97 | if(preferences == null) return false;
98 |
99 | Locale? locale;
100 |
101 | try
102 | {
103 | locale = await preferences!.getPreferredLocale();
104 | }
105 | catch(e)
106 | {
107 | return false;
108 | }
109 |
110 | if(locale != null)
111 | {
112 | await changeLocale(locale);
113 | return true;
114 | }
115 |
116 | return false;
117 | }
118 |
119 | Future _loadDeviceLocale() async
120 | {
121 | try
122 | {
123 | var locale = getCurrentLocale();
124 |
125 | if(locale != null)
126 | {
127 | await changeLocale(locale);
128 | }
129 | }
130 | catch(e)
131 | {
132 | await changeLocale(fallbackLocale);
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/lib/src/interfaces/translate_preferences.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | abstract class ITranslatePreferences
4 | {
5 | Future savePreferredLocale(Locale locale);
6 |
7 | Future getPreferredLocale();
8 | }
9 |
--------------------------------------------------------------------------------
/lib/src/services/locale_file_service.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'package:flutter/services.dart';
3 | import 'package:flutter_translate/src/constants/constants.dart';
4 |
5 | class LocaleFileService
6 | {
7 | static Future