@ -0,0 +1,11 @@
|
||||
>Compile Time Argument |
||||
-flutter |
||||
-build |
||||
-linux |
||||
>Run Time Argument |
||||
-flutter |
||||
-run |
||||
>Compile Time Working Directory |
||||
-logic_circuits_simulator |
||||
>Run Time Working Directory |
||||
-logic_circuits_simulator |
@ -0,0 +1,47 @@
|
||||
# Miscellaneous |
||||
*.class |
||||
*.log |
||||
*.pyc |
||||
*.swp |
||||
.DS_Store |
||||
.atom/ |
||||
.buildlog/ |
||||
.history |
||||
.svn/ |
||||
migrate_working_dir/ |
||||
|
||||
# IntelliJ related |
||||
*.iml |
||||
*.ipr |
||||
*.iws |
||||
.idea/ |
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in |
||||
# VS Code which you may wish to be included in version control, so this line |
||||
# is commented out by default. |
||||
#.vscode/ |
||||
|
||||
# Flutter/Dart/Pub related |
||||
**/doc/api/ |
||||
**/ios/Flutter/.last_build_id |
||||
.dart_tool/ |
||||
.flutter-plugins |
||||
.flutter-plugins-dependencies |
||||
.packages |
||||
.pub-cache/ |
||||
.pub/ |
||||
/build/ |
||||
|
||||
# Web related |
||||
lib/generated_plugin_registrant.dart |
||||
|
||||
# Symbolication related |
||||
app.*.symbols |
||||
|
||||
# Obfuscation related |
||||
app.*.map.json |
||||
|
||||
# Android Studio will place build artifacts here |
||||
/android/app/debug |
||||
/android/app/profile |
||||
/android/app/release |
@ -0,0 +1,42 @@
|
||||
# This file tracks properties of this Flutter project. |
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc. |
||||
# |
||||
# This file should be version controlled. |
||||
|
||||
version: |
||||
revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
channel: beta |
||||
|
||||
project_type: app |
||||
|
||||
# Tracks metadata for the flutter migrate command |
||||
migration: |
||||
platforms: |
||||
- platform: root |
||||
create_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
base_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
- platform: android |
||||
create_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
base_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
- platform: ios |
||||
create_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
base_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
- platform: linux |
||||
create_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
base_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
- platform: web |
||||
create_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
base_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
- platform: windows |
||||
create_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
base_revision: 13a2fb10b838971ce211230f8ffdd094c14af02c |
||||
|
||||
# User provided section |
||||
|
||||
# List of Local paths (relative to this file) that should be |
||||
# ignored by the migrate tool. |
||||
# |
||||
# Files that are not part of the templates will be ignored by default. |
||||
unmanaged_files: |
||||
- 'lib/main.dart' |
||||
- 'ios/Runner.xcodeproj/project.pbxproj' |
@ -0,0 +1,8 @@
|
||||
>JDK Path |
||||
null |
||||
>Main Class |
||||
- |
||||
>Language Tag |
||||
--1 |
||||
>Opened Editors on Main Tab Panel |
||||
-project-root$/lib/main.dart |
@ -0,0 +1,6 @@
|
||||
{ |
||||
"files.exclude": { |
||||
"**/*.freezed.dart": true, |
||||
"**/*.g.dart": true |
||||
} |
||||
} |
@ -0,0 +1,16 @@
|
||||
# logic_circuits_simulator |
||||
|
||||
License project |
||||
|
||||
## Getting Started |
||||
|
||||
This project is a starting point for a Flutter application. |
||||
|
||||
A few resources to get you started if this is your first Flutter project: |
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) |
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) |
||||
|
||||
For help getting started with Flutter development, view the |
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials, |
||||
samples, guidance on mobile development, and a full API reference. |
@ -0,0 +1,33 @@
|
||||
# This file configures the analyzer, which statically analyzes Dart code to |
||||
# check for errors, warnings, and lints. |
||||
# |
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled |
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be |
||||
# invoked from the command line by running `flutter analyze`. |
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps, |
||||
# packages, and plugins designed to encourage good coding practices. |
||||
include: package:flutter_lints/flutter.yaml |
||||
|
||||
linter: |
||||
# The lint rules applied to this project can be customized in the |
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml` |
||||
# included above or to enable additional rules. A list of all available lints |
||||
# and their documentation is published at |
||||
# https://dart-lang.github.io/linter/lints/index.html. |
||||
# |
||||
# Instead of disabling a lint rule for the entire project in the |
||||
# section below, it can also be suppressed for a single line of code |
||||
# or a specific dart file by using the `// ignore: name_of_lint` and |
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file |
||||
# producing the lint. |
||||
rules: |
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule |
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule |
||||
|
||||
# Additional information about this file can be found at |
||||
# https://dart.dev/guides/language/analysis-options |
||||
|
||||
analyzer: |
||||
errors: |
||||
invalid_annotation_target: ignore |
@ -0,0 +1,13 @@
|
||||
gradle-wrapper.jar |
||||
/.gradle |
||||
/captures/ |
||||
/gradlew |
||||
/gradlew.bat |
||||
/local.properties |
||||
GeneratedPluginRegistrant.java |
||||
|
||||
# Remember to never publicly share your keystore. |
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app |
||||
key.properties |
||||
**/*.keystore |
||||
**/*.jks |
@ -0,0 +1,71 @@
|
||||
def localProperties = new Properties() |
||||
def localPropertiesFile = rootProject.file('local.properties') |
||||
if (localPropertiesFile.exists()) { |
||||
localPropertiesFile.withReader('UTF-8') { reader -> |
||||
localProperties.load(reader) |
||||
} |
||||
} |
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk') |
||||
if (flutterRoot == null) { |
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") |
||||
} |
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode') |
||||
if (flutterVersionCode == null) { |
||||
flutterVersionCode = '1' |
||||
} |
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName') |
||||
if (flutterVersionName == null) { |
||||
flutterVersionName = '1.0' |
||||
} |
||||
|
||||
apply plugin: 'com.android.application' |
||||
apply plugin: 'kotlin-android' |
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" |
||||
|
||||
android { |
||||
compileSdkVersion flutter.compileSdkVersion |
||||
ndkVersion flutter.ndkVersion |
||||
|
||||
compileOptions { |
||||
sourceCompatibility JavaVersion.VERSION_1_8 |
||||
targetCompatibility JavaVersion.VERSION_1_8 |
||||
} |
||||
|
||||
kotlinOptions { |
||||
jvmTarget = '1.8' |
||||
} |
||||
|
||||
sourceSets { |
||||
main.java.srcDirs += 'src/main/kotlin' |
||||
} |
||||
|
||||
defaultConfig { |
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). |
||||
applicationId "ro.dcdev.logic_circuits_simulator" |
||||
// You can update the following values to match your application needs. |
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. |
||||
minSdkVersion flutter.minSdkVersion |
||||
targetSdkVersion flutter.targetSdkVersion |
||||
versionCode flutterVersionCode.toInteger() |
||||
versionName flutterVersionName |
||||
} |
||||
|
||||
buildTypes { |
||||
release { |
||||
// TODO: Add your own signing config for the release build. |
||||
// Signing with the debug keys for now, so `flutter run --release` works. |
||||
signingConfig signingConfigs.debug |
||||
} |
||||
} |
||||
} |
||||
|
||||
flutter { |
||||
source '../..' |
||||
} |
||||
|
||||
dependencies { |
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" |
||||
} |
@ -0,0 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="ro.dcdev.logic_circuits_simulator"> |
||||
<!-- The INTERNET permission is required for development. Specifically, |
||||
the Flutter tool needs it to communicate with the running application |
||||
to allow setting breakpoints, to provide hot reload, etc. |
||||
--> |
||||
<uses-permission android:name="android.permission.INTERNET"/> |
||||
</manifest> |
@ -0,0 +1,34 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="ro.dcdev.logic_circuits_simulator"> |
||||
<application |
||||
android:label="logic_circuits_simulator" |
||||
android:name="${applicationName}" |
||||
android:icon="@mipmap/ic_launcher"> |
||||
<activity |
||||
android:name=".MainActivity" |
||||
android:exported="true" |
||||
android:launchMode="singleTop" |
||||
android:theme="@style/LaunchTheme" |
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" |
||||
android:hardwareAccelerated="true" |
||||
android:windowSoftInputMode="adjustResize"> |
||||
<!-- Specifies an Android theme to apply to this Activity as soon as |
||||
the Android process has started. This theme is visible to the user |
||||
while the Flutter UI initializes. After that, this theme continues |
||||
to determine the Window background behind the Flutter UI. --> |
||||
<meta-data |
||||
android:name="io.flutter.embedding.android.NormalTheme" |
||||
android:resource="@style/NormalTheme" |
||||
/> |
||||
<intent-filter> |
||||
<action android:name="android.intent.action.MAIN"/> |
||||
<category android:name="android.intent.category.LAUNCHER"/> |
||||
</intent-filter> |
||||
</activity> |
||||
<!-- Don't delete the meta-data below. |
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> |
||||
<meta-data |
||||
android:name="flutterEmbedding" |
||||
android:value="2" /> |
||||
</application> |
||||
</manifest> |
@ -0,0 +1,6 @@
|
||||
package ro.dcdev.logic_circuits_simulator |
||||
|
||||
import io.flutter.embedding.android.FlutterActivity |
||||
|
||||
class MainActivity: FlutterActivity() { |
||||
} |
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- Modify this file to customize your launch splash screen --> |
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item android:drawable="?android:colorBackground" /> |
||||
|
||||
<!-- You can insert your own image assets here --> |
||||
<!-- <item> |
||||
<bitmap |
||||
android:gravity="center" |
||||
android:src="@mipmap/launch_image" /> |
||||
</item> --> |
||||
</layer-list> |
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- Modify this file to customize your launch splash screen --> |
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item android:drawable="@android:color/white" /> |
||||
|
||||
<!-- You can insert your own image assets here --> |
||||
<!-- <item> |
||||
<bitmap |
||||
android:gravity="center" |
||||
android:src="@mipmap/launch_image" /> |
||||
</item> --> |
||||
</layer-list> |
After Width: | Height: | Size: 544 B |
After Width: | Height: | Size: 442 B |
After Width: | Height: | Size: 721 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on --> |
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> |
||||
<!-- Show a splash screen on the activity. Automatically removed when |
||||
the Flutter engine draws its first frame --> |
||||
<item name="android:windowBackground">@drawable/launch_background</item> |
||||
</style> |
||||
<!-- Theme applied to the Android Window as soon as the process has started. |
||||
This theme determines the color of the Android Window while your |
||||
Flutter UI initializes, as well as behind your Flutter UI while its |
||||
running. |
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. --> |
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar"> |
||||
<item name="android:windowBackground">?android:colorBackground</item> |
||||
</style> |
||||
</resources> |
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off --> |
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar"> |
||||
<!-- Show a splash screen on the activity. Automatically removed when |
||||
the Flutter engine draws its first frame --> |
||||
<item name="android:windowBackground">@drawable/launch_background</item> |
||||
</style> |
||||
<!-- Theme applied to the Android Window as soon as the process has started. |
||||
This theme determines the color of the Android Window while your |
||||
Flutter UI initializes, as well as behind your Flutter UI while its |
||||
running. |
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. --> |
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar"> |
||||
<item name="android:windowBackground">?android:colorBackground</item> |
||||
</style> |
||||
</resources> |
@ -0,0 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="ro.dcdev.logic_circuits_simulator"> |
||||
<!-- The INTERNET permission is required for development. Specifically, |
||||
the Flutter tool needs it to communicate with the running application |
||||
to allow setting breakpoints, to provide hot reload, etc. |
||||
--> |
||||
<uses-permission android:name="android.permission.INTERNET"/> |
||||
</manifest> |
@ -0,0 +1,31 @@
|
||||
buildscript { |
||||
ext.kotlin_version = '1.6.10' |
||||
repositories { |
||||
google() |
||||
mavenCentral() |
||||
} |
||||
|
||||
dependencies { |
||||
classpath 'com.android.tools.build:gradle:7.1.2' |
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |
||||
} |
||||
} |
||||
|
||||
allprojects { |
||||
repositories { |
||||
google() |
||||
mavenCentral() |
||||
} |
||||
} |
||||
|
||||
rootProject.buildDir = '../build' |
||||
subprojects { |
||||
project.buildDir = "${rootProject.buildDir}/${project.name}" |
||||
} |
||||
subprojects { |
||||
project.evaluationDependsOn(':app') |
||||
} |
||||
|
||||
task clean(type: Delete) { |
||||
delete rootProject.buildDir |
||||
} |
@ -0,0 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx1536M |
||||
android.useAndroidX=true |
||||
android.enableJetifier=true |
@ -0,0 +1,6 @@
|
||||
#Fri Jun 23 08:50:38 CEST 2017 |
||||
distributionBase=GRADLE_USER_HOME |
||||
distributionPath=wrapper/dists |
||||
zipStoreBase=GRADLE_USER_HOME |
||||
zipStorePath=wrapper/dists |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip |
@ -0,0 +1,11 @@
|
||||
include ':app' |
||||
|
||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties") |
||||
def properties = new Properties() |
||||
|
||||
assert localPropertiesFile.exists() |
||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } |
||||
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk") |
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties" |
||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" |
@ -0,0 +1,34 @@
|
||||
**/dgph |
||||
*.mode1v3 |
||||
*.mode2v3 |
||||
*.moved-aside |
||||
*.pbxuser |
||||
*.perspectivev3 |
||||
**/*sync/ |
||||
.sconsign.dblite |
||||
.tags* |
||||
**/.vagrant/ |
||||
**/DerivedData/ |
||||
Icon? |
||||
**/Pods/ |
||||
**/.symlinks/ |
||||
profile |
||||
xcuserdata |
||||
**/.generated/ |
||||
Flutter/App.framework |
||||
Flutter/Flutter.framework |
||||
Flutter/Flutter.podspec |
||||
Flutter/Generated.xcconfig |
||||
Flutter/ephemeral/ |
||||
Flutter/app.flx |
||||
Flutter/app.zip |
||||
Flutter/flutter_assets/ |
||||
Flutter/flutter_export_environment.sh |
||||
ServiceDefinitions.json |
||||
Runner/GeneratedPluginRegistrant.* |
||||
|
||||
# Exceptions to above rules. |
||||
!default.mode1v3 |
||||
!default.mode2v3 |
||||
!default.pbxuser |
||||
!default.perspectivev3 |
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>CFBundleDevelopmentRegion</key> |
||||
<string>en</string> |
||||
<key>CFBundleExecutable</key> |
||||
<string>App</string> |
||||
<key>CFBundleIdentifier</key> |
||||
<string>io.flutter.flutter.app</string> |
||||
<key>CFBundleInfoDictionaryVersion</key> |
||||
<string>6.0</string> |
||||
<key>CFBundleName</key> |
||||
<string>App</string> |
||||
<key>CFBundlePackageType</key> |
||||
<string>FMWK</string> |
||||
<key>CFBundleShortVersionString</key> |
||||
<string>1.0</string> |
||||
<key>CFBundleSignature</key> |
||||
<string>????</string> |
||||
<key>CFBundleVersion</key> |
||||
<string>1.0</string> |
||||
<key>MinimumOSVersion</key> |
||||
<string>9.0</string> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,481 @@
|
||||
// !$*UTF8*$! |
||||
{ |
||||
archiveVersion = 1; |
||||
classes = { |
||||
}; |
||||
objectVersion = 50; |
||||
objects = { |
||||
|
||||
/* Begin PBXBuildFile section */ |
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; |
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; |
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; |
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; |
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; |
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; |
||||
/* End PBXBuildFile section */ |
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */ |
||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = { |
||||
isa = PBXCopyFilesBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
dstPath = ""; |
||||
dstSubfolderSpec = 10; |
||||
files = ( |
||||
); |
||||
name = "Embed Frameworks"; |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
}; |
||||
/* End PBXCopyFilesBuildPhase section */ |
||||
|
||||
/* Begin PBXFileReference section */ |
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; |
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; |
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; |
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; |
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; |
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; |
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; |
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; |
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; |
||||
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; |
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; |
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; |
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; |
||||
/* End PBXFileReference section */ |
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */ |
||||
97C146EB1CF9000F007C117D /* Frameworks */ = { |
||||
isa = PBXFrameworksBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
}; |
||||
/* End PBXFrameworksBuildPhase section */ |
||||
|
||||
/* Begin PBXGroup section */ |
||||
9740EEB11CF90186004384FC /* Flutter */ = { |
||||
isa = PBXGroup; |
||||
children = ( |
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, |
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */, |
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */, |
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */, |
||||
); |
||||
name = Flutter; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
97C146E51CF9000F007C117D = { |
||||
isa = PBXGroup; |
||||
children = ( |
||||
9740EEB11CF90186004384FC /* Flutter */, |
||||
97C146F01CF9000F007C117D /* Runner */, |
||||
97C146EF1CF9000F007C117D /* Products */, |
||||
); |
||||
sourceTree = "<group>"; |
||||
}; |
||||
97C146EF1CF9000F007C117D /* Products */ = { |
||||
isa = PBXGroup; |
||||
children = ( |
||||
97C146EE1CF9000F007C117D /* Runner.app */, |
||||
); |
||||
name = Products; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
97C146F01CF9000F007C117D /* Runner */ = { |
||||
isa = PBXGroup; |
||||
children = ( |
||||
97C146FA1CF9000F007C117D /* Main.storyboard */, |
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */, |
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, |
||||
97C147021CF9000F007C117D /* Info.plist */, |
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, |
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, |
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */, |
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, |
||||
); |
||||
path = Runner; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
/* End PBXGroup section */ |
||||
|
||||
/* Begin PBXNativeTarget section */ |
||||
97C146ED1CF9000F007C117D /* Runner */ = { |
||||
isa = PBXNativeTarget; |
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; |
||||
buildPhases = ( |
||||
9740EEB61CF901F6004384FC /* Run Script */, |
||||
97C146EA1CF9000F007C117D /* Sources */, |
||||
97C146EB1CF9000F007C117D /* Frameworks */, |
||||
97C146EC1CF9000F007C117D /* Resources */, |
||||
9705A1C41CF9048500538489 /* Embed Frameworks */, |
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */, |
||||
); |
||||
buildRules = ( |
||||
); |
||||
dependencies = ( |
||||
); |
||||
name = Runner; |
||||
productName = Runner; |
||||
productReference = 97C146EE1CF9000F007C117D /* Runner.app */; |
||||
productType = "com.apple.product-type.application"; |
||||
}; |
||||
/* End PBXNativeTarget section */ |
||||
|
||||
/* Begin PBXProject section */ |
||||
97C146E61CF9000F007C117D /* Project object */ = { |
||||
isa = PBXProject; |
||||
attributes = { |
||||
LastUpgradeCheck = 1300; |
||||
ORGANIZATIONNAME = ""; |
||||
TargetAttributes = { |
||||
97C146ED1CF9000F007C117D = { |
||||
CreatedOnToolsVersion = 7.3.1; |
||||
LastSwiftMigration = 1100; |
||||
}; |
||||
}; |
||||
}; |
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; |
||||
compatibilityVersion = "Xcode 9.3"; |
||||
developmentRegion = en; |
||||
hasScannedForEncodings = 0; |
||||
knownRegions = ( |
||||
en, |
||||
Base, |
||||
); |
||||
mainGroup = 97C146E51CF9000F007C117D; |
||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */; |
||||
projectDirPath = ""; |
||||
projectRoot = ""; |
||||
targets = ( |
||||
97C146ED1CF9000F007C117D /* Runner */, |
||||
); |
||||
}; |
||||
/* End PBXProject section */ |
||||
|
||||
/* Begin PBXResourcesBuildPhase section */ |
||||
97C146EC1CF9000F007C117D /* Resources */ = { |
||||
isa = PBXResourcesBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, |
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, |
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, |
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
}; |
||||
/* End PBXResourcesBuildPhase section */ |
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */ |
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { |
||||
isa = PBXShellScriptBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
); |
||||
inputPaths = ( |
||||
); |
||||
name = "Thin Binary"; |
||||
outputPaths = ( |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
shellPath = /bin/sh; |
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; |
||||
}; |
||||
9740EEB61CF901F6004384FC /* Run Script */ = { |
||||
isa = PBXShellScriptBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
); |
||||
inputPaths = ( |
||||
); |
||||
name = "Run Script"; |
||||
outputPaths = ( |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
shellPath = /bin/sh; |
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; |
||||
}; |
||||
/* End PBXShellScriptBuildPhase section */ |
||||
|
||||
/* Begin PBXSourcesBuildPhase section */ |
||||
97C146EA1CF9000F007C117D /* Sources */ = { |
||||
isa = PBXSourcesBuildPhase; |
||||
buildActionMask = 2147483647; |
||||
files = ( |
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, |
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, |
||||
); |
||||
runOnlyForDeploymentPostprocessing = 0; |
||||
}; |
||||
/* End PBXSourcesBuildPhase section */ |
||||
|
||||
/* Begin PBXVariantGroup section */ |
||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = { |
||||
isa = PBXVariantGroup; |
||||
children = ( |
||||
97C146FB1CF9000F007C117D /* Base */, |
||||
); |
||||
name = Main.storyboard; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { |
||||
isa = PBXVariantGroup; |
||||
children = ( |
||||
97C147001CF9000F007C117D /* Base */, |
||||
); |
||||
name = LaunchScreen.storyboard; |
||||
sourceTree = "<group>"; |
||||
}; |
||||
/* End PBXVariantGroup section */ |
||||
|
||||
/* Begin XCBuildConfiguration section */ |
||||
249021D3217E4FDB00AE95B9 /* Profile */ = { |
||||
isa = XCBuildConfiguration; |
||||
buildSettings = { |
||||
ALWAYS_SEARCH_USER_PATHS = NO; |
||||
CLANG_ANALYZER_NONNULL = YES; |
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; |
||||
CLANG_CXX_LIBRARY = "libc++"; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CLANG_ENABLE_OBJC_ARC = YES; |
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; |
||||
CLANG_WARN_BOOL_CONVERSION = YES; |
||||
CLANG_WARN_COMMA = YES; |
||||
CLANG_WARN_CONSTANT_CONVERSION = YES; |
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; |
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; |
||||
CLANG_WARN_EMPTY_BODY = YES; |
||||
CLANG_WARN_ENUM_CONVERSION = YES; |
||||
CLANG_WARN_INFINITE_RECURSION = YES; |
||||
CLANG_WARN_INT_CONVERSION = YES; |
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; |
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; |
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; |
||||
CLANG_WARN_STRICT_PROTOTYPES = YES; |
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES; |
||||
CLANG_WARN_UNREACHABLE_CODE = YES; |
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; |
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
||||
COPY_PHASE_STRIP = NO; |
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; |
||||
ENABLE_NS_ASSERTIONS = NO; |
||||
ENABLE_STRICT_OBJC_MSGSEND = YES; |
||||
GCC_C_LANGUAGE_STANDARD = gnu99; |
||||
GCC_NO_COMMON_BLOCKS = YES; |
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
||||
GCC_WARN_UNDECLARED_SELECTOR = YES; |
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
||||
GCC_WARN_UNUSED_FUNCTION = YES; |
||||
GCC_WARN_UNUSED_VARIABLE = YES; |
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0; |
||||
MTL_ENABLE_DEBUG_INFO = NO; |
||||
SDKROOT = iphoneos; |
||||
SUPPORTED_PLATFORMS = iphoneos; |
||||
TARGETED_DEVICE_FAMILY = "1,2"; |
||||
VALIDATE_PRODUCT = YES; |
||||
}; |
||||
name = Profile; |
||||
}; |
||||
249021D4217E4FDB00AE95B9 /* Profile */ = { |
||||
isa = XCBuildConfiguration; |
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; |
||||
buildSettings = { |
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
||||
ENABLE_BITCODE = NO; |
||||
INFOPLIST_FILE = Runner/Info.plist; |
||||
LD_RUNPATH_SEARCH_PATHS = ( |
||||
"$(inherited)", |
||||
"@executable_path/Frameworks", |
||||
); |
||||
PRODUCT_BUNDLE_IDENTIFIER = ro.dcdev.logicCircuitsSimulator; |
||||
PRODUCT_NAME = "$(TARGET_NAME)"; |
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
||||
SWIFT_VERSION = 5.0; |
||||
VERSIONING_SYSTEM = "apple-generic"; |
||||
}; |
||||
name = Profile; |
||||
}; |
||||
97C147031CF9000F007C117D /* Debug */ = { |
||||
isa = XCBuildConfiguration; |
||||
buildSettings = { |
||||
ALWAYS_SEARCH_USER_PATHS = NO; |
||||
CLANG_ANALYZER_NONNULL = YES; |
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; |
||||
CLANG_CXX_LIBRARY = "libc++"; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CLANG_ENABLE_OBJC_ARC = YES; |
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; |
||||
CLANG_WARN_BOOL_CONVERSION = YES; |
||||
CLANG_WARN_COMMA = YES; |
||||
CLANG_WARN_CONSTANT_CONVERSION = YES; |
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; |
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; |
||||
CLANG_WARN_EMPTY_BODY = YES; |
||||
CLANG_WARN_ENUM_CONVERSION = YES; |
||||
CLANG_WARN_INFINITE_RECURSION = YES; |
||||
CLANG_WARN_INT_CONVERSION = YES; |
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; |
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; |
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; |
||||
CLANG_WARN_STRICT_PROTOTYPES = YES; |
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES; |
||||
CLANG_WARN_UNREACHABLE_CODE = YES; |
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; |
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
||||
COPY_PHASE_STRIP = NO; |
||||
DEBUG_INFORMATION_FORMAT = dwarf; |
||||
ENABLE_STRICT_OBJC_MSGSEND = YES; |
||||
ENABLE_TESTABILITY = YES; |
||||
GCC_C_LANGUAGE_STANDARD = gnu99; |
||||
GCC_DYNAMIC_NO_PIC = NO; |
||||
GCC_NO_COMMON_BLOCKS = YES; |
||||
GCC_OPTIMIZATION_LEVEL = 0; |
||||
GCC_PREPROCESSOR_DEFINITIONS = ( |
||||
"DEBUG=1", |
||||
"$(inherited)", |
||||
); |
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
||||
GCC_WARN_UNDECLARED_SELECTOR = YES; |
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
||||
GCC_WARN_UNUSED_FUNCTION = YES; |
||||
GCC_WARN_UNUSED_VARIABLE = YES; |
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0; |
||||
MTL_ENABLE_DEBUG_INFO = YES; |
||||
ONLY_ACTIVE_ARCH = YES; |
||||
SDKROOT = iphoneos; |
||||
TARGETED_DEVICE_FAMILY = "1,2"; |
||||
}; |
||||
name = Debug; |
||||
}; |
||||
97C147041CF9000F007C117D /* Release */ = { |
||||
isa = XCBuildConfiguration; |
||||
buildSettings = { |
||||
ALWAYS_SEARCH_USER_PATHS = NO; |
||||
CLANG_ANALYZER_NONNULL = YES; |
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; |
||||
CLANG_CXX_LIBRARY = "libc++"; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CLANG_ENABLE_OBJC_ARC = YES; |
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; |
||||
CLANG_WARN_BOOL_CONVERSION = YES; |
||||
CLANG_WARN_COMMA = YES; |
||||
CLANG_WARN_CONSTANT_CONVERSION = YES; |
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; |
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; |
||||
CLANG_WARN_EMPTY_BODY = YES; |
||||
CLANG_WARN_ENUM_CONVERSION = YES; |
||||
CLANG_WARN_INFINITE_RECURSION = YES; |
||||
CLANG_WARN_INT_CONVERSION = YES; |
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; |
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; |
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; |
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; |
||||
CLANG_WARN_STRICT_PROTOTYPES = YES; |
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES; |
||||
CLANG_WARN_UNREACHABLE_CODE = YES; |
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; |
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; |
||||
COPY_PHASE_STRIP = NO; |
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; |
||||
ENABLE_NS_ASSERTIONS = NO; |
||||
ENABLE_STRICT_OBJC_MSGSEND = YES; |
||||
GCC_C_LANGUAGE_STANDARD = gnu99; |
||||
GCC_NO_COMMON_BLOCKS = YES; |
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
||||
GCC_WARN_UNDECLARED_SELECTOR = YES; |
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
||||
GCC_WARN_UNUSED_FUNCTION = YES; |
||||
GCC_WARN_UNUSED_VARIABLE = YES; |
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0; |
||||
MTL_ENABLE_DEBUG_INFO = NO; |
||||
SDKROOT = iphoneos; |
||||
SUPPORTED_PLATFORMS = iphoneos; |
||||
SWIFT_COMPILATION_MODE = wholemodule; |
||||
SWIFT_OPTIMIZATION_LEVEL = "-O"; |
||||
TARGETED_DEVICE_FAMILY = "1,2"; |
||||
VALIDATE_PRODUCT = YES; |
||||
}; |
||||
name = Release; |
||||
}; |
||||
97C147061CF9000F007C117D /* Debug */ = { |
||||
isa = XCBuildConfiguration; |
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; |
||||
buildSettings = { |
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
||||
ENABLE_BITCODE = NO; |
||||
INFOPLIST_FILE = Runner/Info.plist; |
||||
LD_RUNPATH_SEARCH_PATHS = ( |
||||
"$(inherited)", |
||||
"@executable_path/Frameworks", |
||||
); |
||||
PRODUCT_BUNDLE_IDENTIFIER = ro.dcdev.logicCircuitsSimulator; |
||||
PRODUCT_NAME = "$(TARGET_NAME)"; |
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; |
||||
SWIFT_VERSION = 5.0; |
||||
VERSIONING_SYSTEM = "apple-generic"; |
||||
}; |
||||
name = Debug; |
||||
}; |
||||
97C147071CF9000F007C117D /* Release */ = { |
||||
isa = XCBuildConfiguration; |
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; |
||||
buildSettings = { |
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; |
||||
CLANG_ENABLE_MODULES = YES; |
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; |
||||
ENABLE_BITCODE = NO; |
||||
INFOPLIST_FILE = Runner/Info.plist; |
||||
LD_RUNPATH_SEARCH_PATHS = ( |
||||
"$(inherited)", |
||||
"@executable_path/Frameworks", |
||||
); |
||||
PRODUCT_BUNDLE_IDENTIFIER = ro.dcdev.logicCircuitsSimulator; |
||||
PRODUCT_NAME = "$(TARGET_NAME)"; |
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; |
||||
SWIFT_VERSION = 5.0; |
||||
VERSIONING_SYSTEM = "apple-generic"; |
||||
}; |
||||
name = Release; |
||||
}; |
||||
/* End XCBuildConfiguration section */ |
||||
|
||||
/* Begin XCConfigurationList section */ |
||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { |
||||
isa = XCConfigurationList; |
||||
buildConfigurations = ( |
||||
97C147031CF9000F007C117D /* Debug */, |
||||
97C147041CF9000F007C117D /* Release */, |
||||
249021D3217E4FDB00AE95B9 /* Profile */, |
||||
); |
||||
defaultConfigurationIsVisible = 0; |
||||
defaultConfigurationName = Release; |
||||
}; |
||||
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { |
||||
isa = XCConfigurationList; |
||||
buildConfigurations = ( |
||||
97C147061CF9000F007C117D /* Debug */, |
||||
97C147071CF9000F007C117D /* Release */, |
||||
249021D4217E4FDB00AE95B9 /* Profile */, |
||||
); |
||||
defaultConfigurationIsVisible = 0; |
||||
defaultConfigurationName = Release; |
||||
}; |
||||
/* End XCConfigurationList section */ |
||||
}; |
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */; |
||||
} |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Workspace |
||||
version = "1.0"> |
||||
<FileRef |
||||
location = "self:"> |
||||
</FileRef> |
||||
</Workspace> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>IDEDidComputeMac32BitWarning</key> |
||||
<true/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>PreviewsEnabled</key> |
||||
<false/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Scheme |
||||
LastUpgradeVersion = "1300" |
||||
version = "1.3"> |
||||
<BuildAction |
||||
parallelizeBuildables = "YES" |
||||
buildImplicitDependencies = "YES"> |
||||
<BuildActionEntries> |
||||
<BuildActionEntry |
||||
buildForTesting = "YES" |
||||
buildForRunning = "YES" |
||||
buildForProfiling = "YES" |
||||
buildForArchiving = "YES" |
||||
buildForAnalyzing = "YES"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D" |
||||
BuildableName = "Runner.app" |
||||
BlueprintName = "Runner" |
||||
ReferencedContainer = "container:Runner.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildActionEntry> |
||||
</BuildActionEntries> |
||||
</BuildAction> |
||||
<TestAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
shouldUseLaunchSchemeArgsEnv = "YES"> |
||||
<MacroExpansion> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D" |
||||
BuildableName = "Runner.app" |
||||
BlueprintName = "Runner" |
||||
ReferencedContainer = "container:Runner.xcodeproj"> |
||||
</BuildableReference> |
||||
</MacroExpansion> |
||||
<Testables> |
||||
</Testables> |
||||
</TestAction> |
||||
<LaunchAction |
||||
buildConfiguration = "Debug" |
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" |
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" |
||||
launchStyle = "0" |
||||
useCustomWorkingDirectory = "NO" |
||||
ignoresPersistentStateOnLaunch = "NO" |
||||
debugDocumentVersioning = "YES" |
||||
debugServiceExtension = "internal" |
||||
allowLocationSimulation = "YES"> |
||||
<BuildableProductRunnable |
||||
runnableDebuggingMode = "0"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D" |
||||
BuildableName = "Runner.app" |
||||
BlueprintName = "Runner" |
||||
ReferencedContainer = "container:Runner.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildableProductRunnable> |
||||
</LaunchAction> |
||||
<ProfileAction |
||||
buildConfiguration = "Profile" |
||||
shouldUseLaunchSchemeArgsEnv = "YES" |
||||
savedToolIdentifier = "" |
||||
useCustomWorkingDirectory = "NO" |
||||
debugDocumentVersioning = "YES"> |
||||
<BuildableProductRunnable |
||||
runnableDebuggingMode = "0"> |
||||
<BuildableReference |
||||
BuildableIdentifier = "primary" |
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D" |
||||
BuildableName = "Runner.app" |
||||
BlueprintName = "Runner" |
||||
ReferencedContainer = "container:Runner.xcodeproj"> |
||||
</BuildableReference> |
||||
</BuildableProductRunnable> |
||||
</ProfileAction> |
||||
<AnalyzeAction |
||||
buildConfiguration = "Debug"> |
||||
</AnalyzeAction> |
||||
<ArchiveAction |
||||
buildConfiguration = "Release" |
||||
revealArchiveInOrganizer = "YES"> |
||||
</ArchiveAction> |
||||
</Scheme> |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<Workspace |
||||
version = "1.0"> |
||||
<FileRef |
||||
location = "group:Runner.xcodeproj"> |
||||
</FileRef> |
||||
</Workspace> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>IDEDidComputeMac32BitWarning</key> |
||||
<true/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>PreviewsEnabled</key> |
||||
<false/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,13 @@
|
||||
import UIKit |
||||
import Flutter |
||||
|
||||
@UIApplicationMain |
||||
@objc class AppDelegate: FlutterAppDelegate { |
||||
override func application( |
||||
_ application: UIApplication, |
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? |
||||
) -> Bool { |
||||
GeneratedPluginRegistrant.register(with: self) |
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions) |
||||
} |
||||
} |
@ -0,0 +1,122 @@
|
||||
{ |
||||
"images" : [ |
||||
{ |
||||
"size" : "20x20", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-20x20@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "20x20", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-20x20@3x.png", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-29x29@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-29x29@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-29x29@3x.png", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-40x40@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-40x40@3x.png", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "60x60", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-60x60@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "60x60", |
||||
"idiom" : "iphone", |
||||
"filename" : "Icon-App-60x60@3x.png", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "20x20", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-20x20@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "20x20", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-20x20@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-29x29@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-29x29@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-40x40@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-40x40@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "76x76", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-76x76@1x.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "76x76", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-76x76@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "83.5x83.5", |
||||
"idiom" : "ipad", |
||||
"filename" : "Icon-App-83.5x83.5@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "1024x1024", |
||||
"idiom" : "ios-marketing", |
||||
"filename" : "Icon-App-1024x1024@1x.png", |
||||
"scale" : "1x" |
||||
} |
||||
], |
||||
"info" : { |
||||
"version" : 1, |
||||
"author" : "xcode" |
||||
} |
||||
} |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 564 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1,23 @@
|
||||
{ |
||||
"images" : [ |
||||
{ |
||||
"idiom" : "universal", |
||||
"filename" : "LaunchImage.png", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "universal", |
||||
"filename" : "LaunchImage@2x.png", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "universal", |
||||
"filename" : "LaunchImage@3x.png", |
||||
"scale" : "3x" |
||||
} |
||||
], |
||||
"info" : { |
||||
"version" : 1, |
||||
"author" : "xcode" |
||||
} |
||||
} |
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 68 B |
@ -0,0 +1,5 @@
|
||||
# Launch Screen Assets |
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory. |
||||
|
||||
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. |
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> |
||||
<dependencies> |
||||
<deployment identifier="iOS"/> |
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/> |
||||
</dependencies> |
||||
<scenes> |
||||
<!--View Controller--> |
||||
<scene sceneID="EHf-IW-A2E"> |
||||
<objects> |
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController"> |
||||
<layoutGuides> |
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/> |
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/> |
||||
</layoutGuides> |
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> |
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> |
||||
<subviews> |
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"> |
||||
</imageView> |
||||
</subviews> |
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
||||
<constraints> |
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/> |
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/> |
||||
</constraints> |
||||
</view> |
||||
</viewController> |
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> |
||||
</objects> |
||||
<point key="canvasLocation" x="53" y="375"/> |
||||
</scene> |
||||
</scenes> |
||||
<resources> |
||||
<image name="LaunchImage" width="168" height="185"/> |
||||
</resources> |
||||
</document> |
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r"> |
||||
<dependencies> |
||||
<deployment identifier="iOS"/> |
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> |
||||
</dependencies> |
||||
<scenes> |
||||
<!--Flutter View Controller--> |
||||
<scene sceneID="tne-QT-ifu"> |
||||
<objects> |
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController"> |
||||
<layoutGuides> |
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> |
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> |
||||
</layoutGuides> |
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> |
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/> |
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> |
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> |
||||
</view> |
||||
</viewController> |
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> |
||||
</objects> |
||||
</scene> |
||||
</scenes> |
||||
</document> |
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>CFBundleDevelopmentRegion</key> |
||||
<string>$(DEVELOPMENT_LANGUAGE)</string> |
||||
<key>CFBundleDisplayName</key> |
||||
<string>Logic Circuits Simulator</string> |
||||
<key>CFBundleExecutable</key> |
||||
<string>$(EXECUTABLE_NAME)</string> |
||||
<key>CFBundleIdentifier</key> |
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> |
||||
<key>CFBundleInfoDictionaryVersion</key> |
||||
<string>6.0</string> |
||||
<key>CFBundleName</key> |
||||
<string>logic_circuits_simulator</string> |
||||
<key>CFBundlePackageType</key> |
||||
<string>APPL</string> |
||||
<key>CFBundleShortVersionString</key> |
||||
<string>$(FLUTTER_BUILD_NAME)</string> |
||||
<key>CFBundleSignature</key> |
||||
<string>????</string> |
||||
<key>CFBundleVersion</key> |
||||
<string>$(FLUTTER_BUILD_NUMBER)</string> |
||||
<key>LSRequiresIPhoneOS</key> |
||||
<true/> |
||||
<key>UILaunchStoryboardName</key> |
||||
<string>LaunchScreen</string> |
||||
<key>UIMainStoryboardFile</key> |
||||
<string>Main</string> |
||||
<key>UISupportedInterfaceOrientations</key> |
||||
<array> |
||||
<string>UIInterfaceOrientationPortrait</string> |
||||
<string>UIInterfaceOrientationLandscapeLeft</string> |
||||
<string>UIInterfaceOrientationLandscapeRight</string> |
||||
</array> |
||||
<key>UISupportedInterfaceOrientations~ipad</key> |
||||
<array> |
||||
<string>UIInterfaceOrientationPortrait</string> |
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string> |
||||
<string>UIInterfaceOrientationLandscapeLeft</string> |
||||
<string>UIInterfaceOrientationLandscapeRight</string> |
||||
</array> |
||||
<key>UIViewControllerBasedStatusBarAppearance</key> |
||||
<false/> |
||||
<key>CADisableMinimumFrameDurationOnPhone</key> |
||||
<true/> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1 @@
|
||||
#import "GeneratedPluginRegistrant.h" |
@ -0,0 +1,100 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_hooks/flutter_hooks.dart'; |
||||
import 'package:logic_circuits_simulator/state/projects.dart'; |
||||
import 'package:logic_circuits_simulator/utils/provider_hook.dart'; |
||||
|
||||
class NewProjectDialog extends HookWidget { |
||||
const NewProjectDialog({Key? key}) : super(key: key); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
final projectsState = useProvider<ProjectsState>(); |
||||
final newDialogNameController = useTextEditingController(); |
||||
useListenable(newDialogNameController); |
||||
|
||||
final newProjectAction = useMemoized(() { |
||||
if (newDialogNameController.text.isEmpty) return null; |
||||
return () { |
||||
projectsState.newProject(newDialogNameController.text); |
||||
Navigator.pop(context); |
||||
}; |
||||
}, [newDialogNameController.text]); |
||||
|
||||
return Center( |
||||
child: Card( |
||||
child: IntrinsicWidth( |
||||
child: Column( |
||||
crossAxisAlignment: CrossAxisAlignment.stretch, |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: [ |
||||
Center( |
||||
child: Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: OutlinedButton.icon( |
||||
onPressed: () { |
||||
// TODO: Implement project importing |
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar( |
||||
content: Text('Import coming soon...'), |
||||
)); |
||||
}, |
||||
icon: const Icon(Icons.download), |
||||
label: const Text('Import Project'), |
||||
), |
||||
), |
||||
), |
||||
Row( |
||||
children: [ |
||||
const Expanded( |
||||
child: Padding( |
||||
padding: EdgeInsets.all(8.0), |
||||
child: Divider(), |
||||
), |
||||
), |
||||
Padding( |
||||
padding: const EdgeInsets.symmetric(vertical: 8.0), |
||||
child: Text( |
||||
'OR', |
||||
style: Theme.of(context).textTheme.caption, |
||||
), |
||||
), |
||||
const Expanded( |
||||
child: Padding( |
||||
padding: EdgeInsets.all(8.0), |
||||
child: Divider(), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: Text( |
||||
'New Project', |
||||
style: Theme.of(context).textTheme.headline6, |
||||
textAlign: TextAlign.center, |
||||
), |
||||
), |
||||
Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: Container( |
||||
constraints: const BoxConstraints(minWidth: 300), |
||||
child: TextField( |
||||
controller: newDialogNameController, |
||||
decoration: InputDecoration( |
||||
border: const OutlineInputBorder(), |
||||
labelText: 'Project name', |
||||
suffixIcon: IconButton( |
||||
icon: const Icon(Icons.done), |
||||
onPressed: newProjectAction, |
||||
), |
||||
), |
||||
onSubmitted: newProjectAction == null ? null : (_) => newProjectAction(), |
||||
), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,106 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:intl/date_symbol_data_local.dart'; |
||||
import 'package:intl/intl_standalone.dart'; |
||||
import 'package:logic_circuits_simulator/pages/edit_component.dart'; |
||||
import 'package:logic_circuits_simulator/pages/project.dart'; |
||||
import 'package:logic_circuits_simulator/pages/projects.dart'; |
||||
import 'package:logic_circuits_simulator/pages/settings.dart'; |
||||
import 'package:logic_circuits_simulator/pages_arguments/edit_component.dart'; |
||||
import 'package:logic_circuits_simulator/state/project.dart'; |
||||
import 'package:logic_circuits_simulator/state/projects.dart'; |
||||
import 'package:provider/provider.dart'; |
||||
|
||||
Future<void> main() async { |
||||
runApp(const MyApp()); |
||||
} |
||||
|
||||
class MyApp extends StatelessWidget { |
||||
const MyApp({Key? key}) : super(key: key); |
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return FutureBuilder( |
||||
future: findSystemLocale().then((_) => initializeDateFormatting()).then((_) => true), |
||||
builder: (context, snapshot) { |
||||
if (!snapshot.hasData) { |
||||
// Wait until locale is detected |
||||
return Container(); |
||||
} |
||||
return MultiProvider( |
||||
providers: [ |
||||
ChangeNotifierProvider(create: (_) => ProjectsState()), |
||||
ChangeNotifierProvider(create: (_) => ProjectState()), |
||||
], |
||||
child: MaterialApp( |
||||
title: 'Logic Circuits Simulator', |
||||
theme: ThemeData( |
||||
useMaterial3: true, |
||||
primarySwatch: Colors.amber, |
||||
), |
||||
routes: { |
||||
ProjectsPage.routeName:(context) { |
||||
return const ProjectsPage(); |
||||
}, |
||||
MainPage.routeName:(context) { |
||||
return const MainPage(); |
||||
}, |
||||
SettingsPage.routeName:(context) => const SettingsPage(), |
||||
ProjectPage.routeName: (context) { |
||||
return const ProjectPage(); |
||||
}, |
||||
EditComponentPage.routeName: (context) { |
||||
final arguments = ModalRoute.of(context)!.settings.arguments as EditComponentPageArguments; |
||||
return EditComponentPage( |
||||
component: arguments.component, |
||||
newComponent: arguments.newComponent, |
||||
); |
||||
}, |
||||
}, |
||||
initialRoute: MainPage.routeName, |
||||
), |
||||
); |
||||
} |
||||
); |
||||
} |
||||
} |
||||
|
||||
class MainPage extends StatelessWidget { |
||||
const MainPage({Key? key}) : super(key: key); |
||||
|
||||
static const routeName = '/'; |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Scaffold( |
||||
body: Center( |
||||
child: Column( |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: [ |
||||
Text( |
||||
'Logic Circuits Simulator', |
||||
style: Theme.of(context).textTheme.headline3, |
||||
textAlign: TextAlign.center, |
||||
), |
||||
Column( |
||||
children: [ |
||||
ElevatedButton.icon( |
||||
onPressed: () { |
||||
Navigator.of(context).pushNamed(ProjectsPage.routeName); |
||||
}, |
||||
icon: const Icon(Icons.book), |
||||
label: const Text('Projects'), |
||||
), |
||||
ElevatedButton.icon( |
||||
onPressed: () { |
||||
Navigator.of(context).pushNamed(SettingsPage.routeName); |
||||
}, |
||||
icon: const Icon(Icons.settings), |
||||
label: const Text('Settings'), |
||||
), |
||||
].map((e) => Padding(padding: const EdgeInsets.all(8), child: e,)).toList(growable: false), |
||||
) |
||||
], |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart'; |
||||
|
||||
part 'project.freezed.dart'; |
||||
part 'project.g.dart'; |
||||
|
||||
@freezed |
||||
class ProjectIndex with _$ProjectIndex { |
||||
const factory ProjectIndex({ |
||||
required List<ComponentEntry> components, |
||||
}) = _ProjectIndex; |
||||
|
||||
factory ProjectIndex.fromJson(Map<String, Object?> json) => _$ProjectIndexFromJson(json); |
||||
} |
||||
|
||||
@freezed |
||||
class ComponentEntry with _$ComponentEntry { |
||||
const factory ComponentEntry({ |
||||
required String componentId, |
||||
required String componentName, |
||||
@JsonKey(includeIfNull: false) |
||||
String? componentDescription, |
||||
required List<String> inputs, |
||||
required List<String> outputs, |
||||
@JsonKey(includeIfNull: false) |
||||
List<String>? truthTable, |
||||
}) = _ComponentEntry; |
||||
|
||||
factory ComponentEntry.fromJson(Map<String, Object?> json) => _$ComponentEntryFromJson(json); |
||||
} |
@ -0,0 +1,425 @@
|
||||
// coverage:ignore-file |
||||
// GENERATED CODE - DO NOT MODIFY BY HAND |
||||
// ignore_for_file: type=lint |
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target |
||||
|
||||
part of 'project.dart'; |
||||
|
||||
// ************************************************************************** |
||||
// FreezedGenerator |
||||
// ************************************************************************** |
||||
|
||||
T _$identity<T>(T value) => value; |
||||
|
||||
final _privateConstructorUsedError = UnsupportedError( |
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); |
||||
|
||||
ProjectIndex _$ProjectIndexFromJson(Map<String, dynamic> json) { |
||||
return _ProjectIndex.fromJson(json); |
||||
} |
||||
|
||||
/// @nodoc |
||||
mixin _$ProjectIndex { |
||||
List<ComponentEntry> get components => throw _privateConstructorUsedError; |
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError; |
||||
@JsonKey(ignore: true) |
||||
$ProjectIndexCopyWith<ProjectIndex> get copyWith => |
||||
throw _privateConstructorUsedError; |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class $ProjectIndexCopyWith<$Res> { |
||||
factory $ProjectIndexCopyWith( |
||||
ProjectIndex value, $Res Function(ProjectIndex) then) = |
||||
_$ProjectIndexCopyWithImpl<$Res>; |
||||
$Res call({List<ComponentEntry> components}); |
||||
} |
||||
|
||||
/// @nodoc |
||||
class _$ProjectIndexCopyWithImpl<$Res> implements $ProjectIndexCopyWith<$Res> { |
||||
_$ProjectIndexCopyWithImpl(this._value, this._then); |
||||
|
||||
final ProjectIndex _value; |
||||
// ignore: unused_field |
||||
final $Res Function(ProjectIndex) _then; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? components = freezed, |
||||
}) { |
||||
return _then(_value.copyWith( |
||||
components: components == freezed |
||||
? _value.components |
||||
: components // ignore: cast_nullable_to_non_nullable |
||||
as List<ComponentEntry>, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class _$$_ProjectIndexCopyWith<$Res> |
||||
implements $ProjectIndexCopyWith<$Res> { |
||||
factory _$$_ProjectIndexCopyWith( |
||||
_$_ProjectIndex value, $Res Function(_$_ProjectIndex) then) = |
||||
__$$_ProjectIndexCopyWithImpl<$Res>; |
||||
@override |
||||
$Res call({List<ComponentEntry> components}); |
||||
} |
||||
|
||||
/// @nodoc |
||||
class __$$_ProjectIndexCopyWithImpl<$Res> |
||||
extends _$ProjectIndexCopyWithImpl<$Res> |
||||
implements _$$_ProjectIndexCopyWith<$Res> { |
||||
__$$_ProjectIndexCopyWithImpl( |
||||
_$_ProjectIndex _value, $Res Function(_$_ProjectIndex) _then) |
||||
: super(_value, (v) => _then(v as _$_ProjectIndex)); |
||||
|
||||
@override |
||||
_$_ProjectIndex get _value => super._value as _$_ProjectIndex; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? components = freezed, |
||||
}) { |
||||
return _then(_$_ProjectIndex( |
||||
components: components == freezed |
||||
? _value._components |
||||
: components // ignore: cast_nullable_to_non_nullable |
||||
as List<ComponentEntry>, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
@JsonSerializable() |
||||
class _$_ProjectIndex implements _ProjectIndex { |
||||
const _$_ProjectIndex({required final List<ComponentEntry> components}) |
||||
: _components = components; |
||||
|
||||
factory _$_ProjectIndex.fromJson(Map<String, dynamic> json) => |
||||
_$$_ProjectIndexFromJson(json); |
||||
|
||||
final List<ComponentEntry> _components; |
||||
@override |
||||
List<ComponentEntry> get components { |
||||
// ignore: implicit_dynamic_type |
||||
return EqualUnmodifiableListView(_components); |
||||
} |
||||
|
||||
@override |
||||
String toString() { |
||||
return 'ProjectIndex(components: $components)'; |
||||
} |
||||
|
||||
@override |
||||
bool operator ==(dynamic other) { |
||||
return identical(this, other) || |
||||
(other.runtimeType == runtimeType && |
||||
other is _$_ProjectIndex && |
||||
const DeepCollectionEquality() |
||||
.equals(other._components, _components)); |
||||
} |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
int get hashCode => Object.hash( |
||||
runtimeType, const DeepCollectionEquality().hash(_components)); |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
_$$_ProjectIndexCopyWith<_$_ProjectIndex> get copyWith => |
||||
__$$_ProjectIndexCopyWithImpl<_$_ProjectIndex>(this, _$identity); |
||||
|
||||
@override |
||||
Map<String, dynamic> toJson() { |
||||
return _$$_ProjectIndexToJson(this); |
||||
} |
||||
} |
||||
|
||||
abstract class _ProjectIndex implements ProjectIndex { |
||||
const factory _ProjectIndex( |
||||
{required final List<ComponentEntry> components}) = _$_ProjectIndex; |
||||
|
||||
factory _ProjectIndex.fromJson(Map<String, dynamic> json) = |
||||
_$_ProjectIndex.fromJson; |
||||
|
||||
@override |
||||
List<ComponentEntry> get components => throw _privateConstructorUsedError; |
||||
@override |
||||
@JsonKey(ignore: true) |
||||
_$$_ProjectIndexCopyWith<_$_ProjectIndex> get copyWith => |
||||
throw _privateConstructorUsedError; |
||||
} |
||||
|
||||
ComponentEntry _$ComponentEntryFromJson(Map<String, dynamic> json) { |
||||
return _ComponentEntry.fromJson(json); |
||||
} |
||||
|
||||
/// @nodoc |
||||
mixin _$ComponentEntry { |
||||
String get componentId => throw _privateConstructorUsedError; |
||||
String get componentName => throw _privateConstructorUsedError; |
||||
@JsonKey(includeIfNull: false) |
||||
String? get componentDescription => throw _privateConstructorUsedError; |
||||
List<String> get inputs => throw _privateConstructorUsedError; |
||||
List<String> get outputs => throw _privateConstructorUsedError; |
||||
@JsonKey(includeIfNull: false) |
||||
List<String>? get truthTable => throw _privateConstructorUsedError; |
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError; |
||||
@JsonKey(ignore: true) |
||||
$ComponentEntryCopyWith<ComponentEntry> get copyWith => |
||||
throw _privateConstructorUsedError; |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class $ComponentEntryCopyWith<$Res> { |
||||
factory $ComponentEntryCopyWith( |
||||
ComponentEntry value, $Res Function(ComponentEntry) then) = |
||||
_$ComponentEntryCopyWithImpl<$Res>; |
||||
$Res call( |
||||
{String componentId, |
||||
String componentName, |
||||
@JsonKey(includeIfNull: false) String? componentDescription, |
||||
List<String> inputs, |
||||
List<String> outputs, |
||||
@JsonKey(includeIfNull: false) List<String>? truthTable}); |
||||
} |
||||
|
||||
/// @nodoc |
||||
class _$ComponentEntryCopyWithImpl<$Res> |
||||
implements $ComponentEntryCopyWith<$Res> { |
||||
_$ComponentEntryCopyWithImpl(this._value, this._then); |
||||
|
||||
final ComponentEntry _value; |
||||
// ignore: unused_field |
||||
final $Res Function(ComponentEntry) _then; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? componentId = freezed, |
||||
Object? componentName = freezed, |
||||
Object? componentDescription = freezed, |
||||
Object? inputs = freezed, |
||||
Object? outputs = freezed, |
||||
Object? truthTable = freezed, |
||||
}) { |
||||
return _then(_value.copyWith( |
||||
componentId: componentId == freezed |
||||
? _value.componentId |
||||
: componentId // ignore: cast_nullable_to_non_nullable |
||||
as String, |
||||
componentName: componentName == freezed |
||||
? _value.componentName |
||||
: componentName // ignore: cast_nullable_to_non_nullable |
||||
as String, |
||||
componentDescription: componentDescription == freezed |
||||
? _value.componentDescription |
||||
: componentDescription // ignore: cast_nullable_to_non_nullable |
||||
as String?, |
||||
inputs: inputs == freezed |
||||
? _value.inputs |
||||
: inputs // ignore: cast_nullable_to_non_nullable |
||||
as List<String>, |
||||
outputs: outputs == freezed |
||||
? _value.outputs |
||||
: outputs // ignore: cast_nullable_to_non_nullable |
||||
as List<String>, |
||||
truthTable: truthTable == freezed |
||||
? _value.truthTable |
||||
: truthTable // ignore: cast_nullable_to_non_nullable |
||||
as List<String>?, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class _$$_ComponentEntryCopyWith<$Res> |
||||
implements $ComponentEntryCopyWith<$Res> { |
||||
factory _$$_ComponentEntryCopyWith( |
||||
_$_ComponentEntry value, $Res Function(_$_ComponentEntry) then) = |
||||
__$$_ComponentEntryCopyWithImpl<$Res>; |
||||
@override |
||||
$Res call( |
||||
{String componentId, |
||||
String componentName, |
||||
@JsonKey(includeIfNull: false) String? componentDescription, |
||||
List<String> inputs, |
||||
List<String> outputs, |
||||
@JsonKey(includeIfNull: false) List<String>? truthTable}); |
||||
} |
||||
|
||||
/// @nodoc |
||||
class __$$_ComponentEntryCopyWithImpl<$Res> |
||||
extends _$ComponentEntryCopyWithImpl<$Res> |
||||
implements _$$_ComponentEntryCopyWith<$Res> { |
||||
__$$_ComponentEntryCopyWithImpl( |
||||
_$_ComponentEntry _value, $Res Function(_$_ComponentEntry) _then) |
||||
: super(_value, (v) => _then(v as _$_ComponentEntry)); |
||||
|
||||
@override |
||||
_$_ComponentEntry get _value => super._value as _$_ComponentEntry; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? componentId = freezed, |
||||
Object? componentName = freezed, |
||||
Object? componentDescription = freezed, |
||||
Object? inputs = freezed, |
||||
Object? outputs = freezed, |
||||
Object? truthTable = freezed, |
||||
}) { |
||||
return _then(_$_ComponentEntry( |
||||
componentId: componentId == freezed |
||||
? _value.componentId |
||||
: componentId // ignore: cast_nullable_to_non_nullable |
||||
as String, |
||||
componentName: componentName == freezed |
||||
? _value.componentName |
||||
: componentName // ignore: cast_nullable_to_non_nullable |
||||
as String, |
||||
componentDescription: componentDescription == freezed |
||||
? _value.componentDescription |
||||
: componentDescription // ignore: cast_nullable_to_non_nullable |
||||
as String?, |
||||
inputs: inputs == freezed |
||||
? _value._inputs |
||||
: inputs // ignore: cast_nullable_to_non_nullable |
||||
as List<String>, |
||||
outputs: outputs == freezed |
||||
? _value._outputs |
||||
: outputs // ignore: cast_nullable_to_non_nullable |
||||
as List<String>, |
||||
truthTable: truthTable == freezed |
||||
? _value._truthTable |
||||
: truthTable // ignore: cast_nullable_to_non_nullable |
||||
as List<String>?, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
@JsonSerializable() |
||||
class _$_ComponentEntry implements _ComponentEntry { |
||||
const _$_ComponentEntry( |
||||
{required this.componentId, |
||||
required this.componentName, |
||||
@JsonKey(includeIfNull: false) this.componentDescription, |
||||
required final List<String> inputs, |
||||
required final List<String> outputs, |
||||
@JsonKey(includeIfNull: false) final List<String>? truthTable}) |
||||
: _inputs = inputs, |
||||
_outputs = outputs, |
||||
_truthTable = truthTable; |
||||
|
||||
factory _$_ComponentEntry.fromJson(Map<String, dynamic> json) => |
||||
_$$_ComponentEntryFromJson(json); |
||||
|
||||
@override |
||||
final String componentId; |
||||
@override |
||||
final String componentName; |
||||
@override |
||||
@JsonKey(includeIfNull: false) |
||||
final String? componentDescription; |
||||
final List<String> _inputs; |
||||
@override |
||||
List<String> get inputs { |
||||
// ignore: implicit_dynamic_type |
||||
return EqualUnmodifiableListView(_inputs); |
||||
} |
||||
|
||||
final List<String> _outputs; |
||||
@override |
||||
List<String> get outputs { |
||||
// ignore: implicit_dynamic_type |
||||
return EqualUnmodifiableListView(_outputs); |
||||
} |
||||
|
||||
final List<String>? _truthTable; |
||||
@override |
||||
@JsonKey(includeIfNull: false) |
||||
List<String>? get truthTable { |
||||
final value = _truthTable; |
||||
if (value == null) return null; |
||||
// ignore: implicit_dynamic_type |
||||
return EqualUnmodifiableListView(value); |
||||
} |
||||
|
||||
@override |
||||
String toString() { |
||||
return 'ComponentEntry(componentId: $componentId, componentName: $componentName, componentDescription: $componentDescription, inputs: $inputs, outputs: $outputs, truthTable: $truthTable)'; |
||||
} |
||||
|
||||
@override |
||||
bool operator ==(dynamic other) { |
||||
return identical(this, other) || |
||||
(other.runtimeType == runtimeType && |
||||
other is _$_ComponentEntry && |
||||
const DeepCollectionEquality() |
||||
.equals(other.componentId, componentId) && |
||||
const DeepCollectionEquality() |
||||
.equals(other.componentName, componentName) && |
||||
const DeepCollectionEquality() |
||||
.equals(other.componentDescription, componentDescription) && |
||||
const DeepCollectionEquality().equals(other._inputs, _inputs) && |
||||
const DeepCollectionEquality().equals(other._outputs, _outputs) && |
||||
const DeepCollectionEquality() |
||||
.equals(other._truthTable, _truthTable)); |
||||
} |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
int get hashCode => Object.hash( |
||||
runtimeType, |
||||
const DeepCollectionEquality().hash(componentId), |
||||
const DeepCollectionEquality().hash(componentName), |
||||
const DeepCollectionEquality().hash(componentDescription), |
||||
const DeepCollectionEquality().hash(_inputs), |
||||
const DeepCollectionEquality().hash(_outputs), |
||||
const DeepCollectionEquality().hash(_truthTable)); |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
_$$_ComponentEntryCopyWith<_$_ComponentEntry> get copyWith => |
||||
__$$_ComponentEntryCopyWithImpl<_$_ComponentEntry>(this, _$identity); |
||||
|
||||
@override |
||||
Map<String, dynamic> toJson() { |
||||
return _$$_ComponentEntryToJson(this); |
||||
} |
||||
} |
||||
|
||||
abstract class _ComponentEntry implements ComponentEntry { |
||||
const factory _ComponentEntry( |
||||
{required final String componentId, |
||||
required final String componentName, |
||||
@JsonKey(includeIfNull: false) final String? componentDescription, |
||||
required final List<String> inputs, |
||||
required final List<String> outputs, |
||||
@JsonKey(includeIfNull: false) final List<String>? truthTable}) = |
||||
_$_ComponentEntry; |
||||
|
||||
factory _ComponentEntry.fromJson(Map<String, dynamic> json) = |
||||
_$_ComponentEntry.fromJson; |
||||
|
||||
@override |
||||
String get componentId => throw _privateConstructorUsedError; |
||||
@override |
||||
String get componentName => throw _privateConstructorUsedError; |
||||
@override |
||||
@JsonKey(includeIfNull: false) |
||||
String? get componentDescription => throw _privateConstructorUsedError; |
||||
@override |
||||
List<String> get inputs => throw _privateConstructorUsedError; |
||||
@override |
||||
List<String> get outputs => throw _privateConstructorUsedError; |
||||
@override |
||||
@JsonKey(includeIfNull: false) |
||||
List<String>? get truthTable => throw _privateConstructorUsedError; |
||||
@override |
||||
@JsonKey(ignore: true) |
||||
_$$_ComponentEntryCopyWith<_$_ComponentEntry> get copyWith => |
||||
throw _privateConstructorUsedError; |
||||
} |
@ -0,0 +1,52 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND |
||||
|
||||
part of 'project.dart'; |
||||
|
||||
// ************************************************************************** |
||||
// JsonSerializableGenerator |
||||
// ************************************************************************** |
||||
|
||||
_$_ProjectIndex _$$_ProjectIndexFromJson(Map<String, dynamic> json) => |
||||
_$_ProjectIndex( |
||||
components: (json['components'] as List<dynamic>) |
||||
.map((e) => ComponentEntry.fromJson(e as Map<String, dynamic>)) |
||||
.toList(), |
||||
); |
||||
|
||||
Map<String, dynamic> _$$_ProjectIndexToJson(_$_ProjectIndex instance) => |
||||
<String, dynamic>{ |
||||
'components': instance.components, |
||||
}; |
||||
|
||||
_$_ComponentEntry _$$_ComponentEntryFromJson(Map<String, dynamic> json) => |
||||
_$_ComponentEntry( |
||||
componentId: json['componentId'] as String, |
||||
componentName: json['componentName'] as String, |
||||
componentDescription: json['componentDescription'] as String?, |
||||
inputs: |
||||
(json['inputs'] as List<dynamic>).map((e) => e as String).toList(), |
||||
outputs: |
||||
(json['outputs'] as List<dynamic>).map((e) => e as String).toList(), |
||||
truthTable: (json['truthTable'] as List<dynamic>?) |
||||
?.map((e) => e as String) |
||||
.toList(), |
||||
); |
||||
|
||||
Map<String, dynamic> _$$_ComponentEntryToJson(_$_ComponentEntry instance) { |
||||
final val = <String, dynamic>{ |
||||
'componentId': instance.componentId, |
||||
'componentName': instance.componentName, |
||||
}; |
||||
|
||||
void writeNotNull(String key, dynamic value) { |
||||
if (value != null) { |
||||
val[key] = value; |
||||
} |
||||
} |
||||
|
||||
writeNotNull('componentDescription', instance.componentDescription); |
||||
val['inputs'] = instance.inputs; |
||||
val['outputs'] = instance.outputs; |
||||
writeNotNull('truthTable', instance.truthTable); |
||||
return val; |
||||
} |
@ -0,0 +1,24 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart'; |
||||
|
||||
part 'projects.freezed.dart'; |
||||
part 'projects.g.dart'; |
||||
|
||||
@freezed |
||||
class ProjectsIndex with _$ProjectsIndex { |
||||
const factory ProjectsIndex({ |
||||
required List<ProjectEntry> projects, |
||||
}) = _ProjectsIndex; |
||||
|
||||
factory ProjectsIndex.fromJson(Map<String, Object?> json) => _$ProjectsIndexFromJson(json); |
||||
} |
||||
|
||||
@freezed |
||||
class ProjectEntry with _$ProjectEntry { |
||||
const factory ProjectEntry({ |
||||
required DateTime lastUpdate, |
||||
required String projectName, |
||||
required String projectId, |
||||
}) = _ProjectEntry; |
||||
|
||||
factory ProjectEntry.fromJson(Map<String, Object?> json) => _$ProjectEntryFromJson(json); |
||||
} |
@ -0,0 +1,327 @@
|
||||
// coverage:ignore-file |
||||
// GENERATED CODE - DO NOT MODIFY BY HAND |
||||
// ignore_for_file: type=lint |
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target |
||||
|
||||
part of 'projects.dart'; |
||||
|
||||
// ************************************************************************** |
||||
// FreezedGenerator |
||||
// ************************************************************************** |
||||
|
||||
T _$identity<T>(T value) => value; |
||||
|
||||
final _privateConstructorUsedError = UnsupportedError( |
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); |
||||
|
||||
ProjectsIndex _$ProjectsIndexFromJson(Map<String, dynamic> json) { |
||||
return _ProjectsIndex.fromJson(json); |
||||
} |
||||
|
||||
/// @nodoc |
||||
mixin _$ProjectsIndex { |
||||
List<ProjectEntry> get projects => throw _privateConstructorUsedError; |
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError; |
||||
@JsonKey(ignore: true) |
||||
$ProjectsIndexCopyWith<ProjectsIndex> get copyWith => |
||||
throw _privateConstructorUsedError; |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class $ProjectsIndexCopyWith<$Res> { |
||||
factory $ProjectsIndexCopyWith( |
||||
ProjectsIndex value, $Res Function(ProjectsIndex) then) = |
||||
_$ProjectsIndexCopyWithImpl<$Res>; |
||||
$Res call({List<ProjectEntry> projects}); |
||||
} |
||||
|
||||
/// @nodoc |
||||
class _$ProjectsIndexCopyWithImpl<$Res> |
||||
implements $ProjectsIndexCopyWith<$Res> { |
||||
_$ProjectsIndexCopyWithImpl(this._value, this._then); |
||||
|
||||
final ProjectsIndex _value; |
||||
// ignore: unused_field |
||||
final $Res Function(ProjectsIndex) _then; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? projects = freezed, |
||||
}) { |
||||
return _then(_value.copyWith( |
||||
projects: projects == freezed |
||||
? _value.projects |
||||
: projects // ignore: cast_nullable_to_non_nullable |
||||
as List<ProjectEntry>, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class _$$_ProjectsIndexCopyWith<$Res> |
||||
implements $ProjectsIndexCopyWith<$Res> { |
||||
factory _$$_ProjectsIndexCopyWith( |
||||
_$_ProjectsIndex value, $Res Function(_$_ProjectsIndex) then) = |
||||
__$$_ProjectsIndexCopyWithImpl<$Res>; |
||||
@override |
||||
$Res call({List<ProjectEntry> projects}); |
||||
} |
||||
|
||||
/// @nodoc |
||||
class __$$_ProjectsIndexCopyWithImpl<$Res> |
||||
extends _$ProjectsIndexCopyWithImpl<$Res> |
||||
implements _$$_ProjectsIndexCopyWith<$Res> { |
||||
__$$_ProjectsIndexCopyWithImpl( |
||||
_$_ProjectsIndex _value, $Res Function(_$_ProjectsIndex) _then) |
||||
: super(_value, (v) => _then(v as _$_ProjectsIndex)); |
||||
|
||||
@override |
||||
_$_ProjectsIndex get _value => super._value as _$_ProjectsIndex; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? projects = freezed, |
||||
}) { |
||||
return _then(_$_ProjectsIndex( |
||||
projects: projects == freezed |
||||
? _value._projects |
||||
: projects // ignore: cast_nullable_to_non_nullable |
||||
as List<ProjectEntry>, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
@JsonSerializable() |
||||
class _$_ProjectsIndex implements _ProjectsIndex { |
||||
const _$_ProjectsIndex({required final List<ProjectEntry> projects}) |
||||
: _projects = projects; |
||||
|
||||
factory _$_ProjectsIndex.fromJson(Map<String, dynamic> json) => |
||||
_$$_ProjectsIndexFromJson(json); |
||||
|
||||
final List<ProjectEntry> _projects; |
||||
@override |
||||
List<ProjectEntry> get projects { |
||||
// ignore: implicit_dynamic_type |
||||
return EqualUnmodifiableListView(_projects); |
||||
} |
||||
|
||||
@override |
||||
String toString() { |
||||
return 'ProjectsIndex(projects: $projects)'; |
||||
} |
||||
|
||||
@override |
||||
bool operator ==(dynamic other) { |
||||
return identical(this, other) || |
||||
(other.runtimeType == runtimeType && |
||||
other is _$_ProjectsIndex && |
||||
const DeepCollectionEquality().equals(other._projects, _projects)); |
||||
} |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
int get hashCode => |
||||
Object.hash(runtimeType, const DeepCollectionEquality().hash(_projects)); |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
_$$_ProjectsIndexCopyWith<_$_ProjectsIndex> get copyWith => |
||||
__$$_ProjectsIndexCopyWithImpl<_$_ProjectsIndex>(this, _$identity); |
||||
|
||||
@override |
||||
Map<String, dynamic> toJson() { |
||||
return _$$_ProjectsIndexToJson(this); |
||||
} |
||||
} |
||||
|
||||
abstract class _ProjectsIndex implements ProjectsIndex { |
||||
const factory _ProjectsIndex({required final List<ProjectEntry> projects}) = |
||||
_$_ProjectsIndex; |
||||
|
||||
factory _ProjectsIndex.fromJson(Map<String, dynamic> json) = |
||||
_$_ProjectsIndex.fromJson; |
||||
|
||||
@override |
||||
List<ProjectEntry> get projects => throw _privateConstructorUsedError; |
||||
@override |
||||
@JsonKey(ignore: true) |
||||
_$$_ProjectsIndexCopyWith<_$_ProjectsIndex> get copyWith => |
||||
throw _privateConstructorUsedError; |
||||
} |
||||
|
||||
ProjectEntry _$ProjectEntryFromJson(Map<String, dynamic> json) { |
||||
return _ProjectEntry.fromJson(json); |
||||
} |
||||
|
||||
/// @nodoc |
||||
mixin _$ProjectEntry { |
||||
DateTime get lastUpdate => throw _privateConstructorUsedError; |
||||
String get projectName => throw _privateConstructorUsedError; |
||||
String get projectId => throw _privateConstructorUsedError; |
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError; |
||||
@JsonKey(ignore: true) |
||||
$ProjectEntryCopyWith<ProjectEntry> get copyWith => |
||||
throw _privateConstructorUsedError; |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class $ProjectEntryCopyWith<$Res> { |
||||
factory $ProjectEntryCopyWith( |
||||
ProjectEntry value, $Res Function(ProjectEntry) then) = |
||||
_$ProjectEntryCopyWithImpl<$Res>; |
||||
$Res call({DateTime lastUpdate, String projectName, String projectId}); |
||||
} |
||||
|
||||
/// @nodoc |
||||
class _$ProjectEntryCopyWithImpl<$Res> implements $ProjectEntryCopyWith<$Res> { |
||||
_$ProjectEntryCopyWithImpl(this._value, this._then); |
||||
|
||||
final ProjectEntry _value; |
||||
// ignore: unused_field |
||||
final $Res Function(ProjectEntry) _then; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? lastUpdate = freezed, |
||||
Object? projectName = freezed, |
||||
Object? projectId = freezed, |
||||
}) { |
||||
return _then(_value.copyWith( |
||||
lastUpdate: lastUpdate == freezed |
||||
? _value.lastUpdate |
||||
: lastUpdate // ignore: cast_nullable_to_non_nullable |
||||
as DateTime, |
||||
projectName: projectName == freezed |
||||
? _value.projectName |
||||
: projectName // ignore: cast_nullable_to_non_nullable |
||||
as String, |
||||
projectId: projectId == freezed |
||||
? _value.projectId |
||||
: projectId // ignore: cast_nullable_to_non_nullable |
||||
as String, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class _$$_ProjectEntryCopyWith<$Res> |
||||
implements $ProjectEntryCopyWith<$Res> { |
||||
factory _$$_ProjectEntryCopyWith( |
||||
_$_ProjectEntry value, $Res Function(_$_ProjectEntry) then) = |
||||
__$$_ProjectEntryCopyWithImpl<$Res>; |
||||
@override |
||||
$Res call({DateTime lastUpdate, String projectName, String projectId}); |
||||
} |
||||
|
||||
/// @nodoc |
||||
class __$$_ProjectEntryCopyWithImpl<$Res> |
||||
extends _$ProjectEntryCopyWithImpl<$Res> |
||||
implements _$$_ProjectEntryCopyWith<$Res> { |
||||
__$$_ProjectEntryCopyWithImpl( |
||||
_$_ProjectEntry _value, $Res Function(_$_ProjectEntry) _then) |
||||
: super(_value, (v) => _then(v as _$_ProjectEntry)); |
||||
|
||||
@override |
||||
_$_ProjectEntry get _value => super._value as _$_ProjectEntry; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? lastUpdate = freezed, |
||||
Object? projectName = freezed, |
||||
Object? projectId = freezed, |
||||
}) { |
||||
return _then(_$_ProjectEntry( |
||||
lastUpdate: lastUpdate == freezed |
||||
? _value.lastUpdate |
||||
: lastUpdate // ignore: cast_nullable_to_non_nullable |
||||
as DateTime, |
||||
projectName: projectName == freezed |
||||
? _value.projectName |
||||
: projectName // ignore: cast_nullable_to_non_nullable |
||||
as String, |
||||
projectId: projectId == freezed |
||||
? _value.projectId |
||||
: projectId // ignore: cast_nullable_to_non_nullable |
||||
as String, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
@JsonSerializable() |
||||
class _$_ProjectEntry implements _ProjectEntry { |
||||
const _$_ProjectEntry( |
||||
{required this.lastUpdate, |
||||
required this.projectName, |
||||
required this.projectId}); |
||||
|
||||
factory _$_ProjectEntry.fromJson(Map<String, dynamic> json) => |
||||
_$$_ProjectEntryFromJson(json); |
||||
|
||||
@override |
||||
final DateTime lastUpdate; |
||||
@override |
||||
final String projectName; |
||||
@override |
||||
final String projectId; |
||||
|
||||
@override |
||||
String toString() { |
||||
return 'ProjectEntry(lastUpdate: $lastUpdate, projectName: $projectName, projectId: $projectId)'; |
||||
} |
||||
|
||||
@override |
||||
bool operator ==(dynamic other) { |
||||
return identical(this, other) || |
||||
(other.runtimeType == runtimeType && |
||||
other is _$_ProjectEntry && |
||||
const DeepCollectionEquality() |
||||
.equals(other.lastUpdate, lastUpdate) && |
||||
const DeepCollectionEquality() |
||||
.equals(other.projectName, projectName) && |
||||
const DeepCollectionEquality().equals(other.projectId, projectId)); |
||||
} |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
int get hashCode => Object.hash( |
||||
runtimeType, |
||||
const DeepCollectionEquality().hash(lastUpdate), |
||||
const DeepCollectionEquality().hash(projectName), |
||||
const DeepCollectionEquality().hash(projectId)); |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
_$$_ProjectEntryCopyWith<_$_ProjectEntry> get copyWith => |
||||
__$$_ProjectEntryCopyWithImpl<_$_ProjectEntry>(this, _$identity); |
||||
|
||||
@override |
||||
Map<String, dynamic> toJson() { |
||||
return _$$_ProjectEntryToJson(this); |
||||
} |
||||
} |
||||
|
||||
abstract class _ProjectEntry implements ProjectEntry { |
||||
const factory _ProjectEntry( |
||||
{required final DateTime lastUpdate, |
||||
required final String projectName, |
||||
required final String projectId}) = _$_ProjectEntry; |
||||
|
||||
factory _ProjectEntry.fromJson(Map<String, dynamic> json) = |
||||
_$_ProjectEntry.fromJson; |
||||
|
||||
@override |
||||
DateTime get lastUpdate => throw _privateConstructorUsedError; |
||||
@override |
||||
String get projectName => throw _privateConstructorUsedError; |
||||
@override |
||||
String get projectId => throw _privateConstructorUsedError; |
||||
@override |
||||
@JsonKey(ignore: true) |
||||
_$$_ProjectEntryCopyWith<_$_ProjectEntry> get copyWith => |
||||
throw _privateConstructorUsedError; |
||||
} |
@ -0,0 +1,33 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND |
||||
|
||||
part of 'projects.dart'; |
||||
|
||||
// ************************************************************************** |
||||
// JsonSerializableGenerator |
||||
// ************************************************************************** |
||||
|
||||
_$_ProjectsIndex _$$_ProjectsIndexFromJson(Map<String, dynamic> json) => |
||||
_$_ProjectsIndex( |
||||
projects: (json['projects'] as List<dynamic>) |
||||
.map((e) => ProjectEntry.fromJson(e as Map<String, dynamic>)) |
||||
.toList(), |
||||
); |
||||
|
||||
Map<String, dynamic> _$$_ProjectsIndexToJson(_$_ProjectsIndex instance) => |
||||
<String, dynamic>{ |
||||
'projects': instance.projects, |
||||
}; |
||||
|
||||
_$_ProjectEntry _$$_ProjectEntryFromJson(Map<String, dynamic> json) => |
||||
_$_ProjectEntry( |
||||
lastUpdate: DateTime.parse(json['lastUpdate'] as String), |
||||
projectName: json['projectName'] as String, |
||||
projectId: json['projectId'] as String, |
||||
); |
||||
|
||||
Map<String, dynamic> _$$_ProjectEntryToJson(_$_ProjectEntry instance) => |
||||
<String, dynamic>{ |
||||
'lastUpdate': instance.lastUpdate.toIso8601String(), |
||||
'projectName': instance.projectName, |
||||
'projectId': instance.projectId, |
||||
}; |
@ -0,0 +1,185 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_hooks/flutter_hooks.dart'; |
||||
import 'package:logic_circuits_simulator/models/project.dart'; |
||||
import 'package:logic_circuits_simulator/state/project.dart'; |
||||
import 'package:logic_circuits_simulator/utils/provider_hook.dart'; |
||||
|
||||
class EditComponentPage extends HookWidget { |
||||
final bool newComponent; |
||||
final ComponentEntry component; |
||||
|
||||
const EditComponentPage({Key? key, this.newComponent = false, required this.component}) : super(key: key); |
||||
|
||||
static const String routeName = '/project/component/edit'; |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
final anySave = useState(false); |
||||
final projectState = useProvider<ProjectState>(); |
||||
final ce = projectState.index.components.where((c) => c.componentId == component.componentId).first; |
||||
final componentNameEditingController = useTextEditingController(text: ce.componentName); |
||||
useValueListenable(componentNameEditingController); |
||||
final dirty = useMemoized(() { |
||||
if (componentNameEditingController.text.isEmpty) { |
||||
// Don't allow saving empty name |
||||
return false; |
||||
} |
||||
if (componentNameEditingController.text != ce.componentName) { |
||||
return true; |
||||
} |
||||
return false; |
||||
}, [componentNameEditingController.text, ce.componentName]); |
||||
|
||||
return WillPopScope( |
||||
onWillPop: () async { |
||||
if (!dirty && !newComponent) { |
||||
return true; |
||||
} else if (!dirty && anySave.value) { |
||||
return true; |
||||
} |
||||
final dialogResult = await showDialog( |
||||
context: context, |
||||
builder: (context) { |
||||
return AlertDialog( |
||||
actions: [ |
||||
TextButton( |
||||
onPressed: () => Navigator.of(context).pop(), |
||||
child: const Text('Cancel'), |
||||
), |
||||
ElevatedButton( |
||||
onPressed: () { |
||||
Navigator.of(context).pop(true); |
||||
}, |
||||
style: ButtonStyle( |
||||
backgroundColor: MaterialStateProperty.all(Colors.red), |
||||
), |
||||
child: const Text('Discard'), |
||||
), |
||||
], |
||||
title: Text('Cancel ${newComponent ? 'Creation' : 'Editing'}'), |
||||
content: Text(newComponent ? 'A new component will not be created.' : 'Are you sure you want to discard the changes?'), |
||||
); |
||||
} |
||||
); |
||||
return dialogResult == true; |
||||
}, |
||||
child: Scaffold( |
||||
appBar: AppBar( |
||||
title: Text(newComponent ? 'New Component' : 'Edit Component'), |
||||
centerTitle: true, |
||||
), |
||||
body: CustomScrollView( |
||||
slivers: [ |
||||
SliverPadding( |
||||
padding: const EdgeInsets.all(8), |
||||
sliver: SliverToBoxAdapter( |
||||
child: TextField( |
||||
controller: componentNameEditingController, |
||||
decoration: const InputDecoration( |
||||
border: OutlineInputBorder(), |
||||
labelText: 'Component name', |
||||
), |
||||
), |
||||
), |
||||
), |
||||
SliverToBoxAdapter( |
||||
child: Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: Text( |
||||
'Inputs', |
||||
style: Theme.of(context).textTheme.headline5, |
||||
), |
||||
), |
||||
), |
||||
SliverList( |
||||
delegate: SliverChildBuilderDelegate( |
||||
(context, i) => ListTile(title: Text(ce.inputs[i]),), |
||||
childCount: ce.inputs.length, |
||||
), |
||||
), |
||||
SliverToBoxAdapter( |
||||
child: Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: Text( |
||||
'Outputs', |
||||
style: Theme.of(context).textTheme.headline5, |
||||
), |
||||
), |
||||
), |
||||
SliverList( |
||||
delegate: SliverChildBuilderDelegate( |
||||
(context, i) => ListTile(title: Text(ce.outputs[i]),), |
||||
childCount: ce.outputs.length, |
||||
), |
||||
), |
||||
if (ce.truthTable != null) ...[ |
||||
SliverToBoxAdapter( |
||||
child: Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: Text( |
||||
'Truth Table', |
||||
style: Theme.of(context).textTheme.headline5, |
||||
), |
||||
), |
||||
), |
||||
SliverToBoxAdapter( |
||||
child: Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: TruthTableEditor( |
||||
truthTable: ce.truthTable!, |
||||
inputs: ce.inputs, |
||||
outputs: ce.outputs, |
||||
), |
||||
), |
||||
) |
||||
], |
||||
], |
||||
), |
||||
floatingActionButton: !dirty ? null : FloatingActionButton( |
||||
onPressed: () async { |
||||
if (componentNameEditingController.text.isNotEmpty) { |
||||
await projectState.editComponent(component.copyWith(componentName: componentNameEditingController.text)); |
||||
} |
||||
anySave.value = true; |
||||
// TODO: Implement saving |
||||
}, |
||||
tooltip: 'Save Component', |
||||
child: const Icon(Icons.save), |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
||||
|
||||
class TruthTableEditor extends StatelessWidget { |
||||
final List<String> inputs; |
||||
final List<String> outputs; |
||||
final List<String> truthTable; |
||||
|
||||
const TruthTableEditor({Key? key, required this.inputs, required this.outputs, required this.truthTable}) : super(key: key); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Table( |
||||
defaultColumnWidth: const IntrinsicColumnWidth(), |
||||
children: List.generate( |
||||
truthTable.length + 1, |
||||
(index) { |
||||
if (index == 0) { |
||||
return TableRow( |
||||
children: inputs.map((e) => Text(e)).followedBy(outputs.map((e) => Text(e))).toList(), |
||||
); |
||||
} |
||||
final inputBinary = (index - 1).toRadixString(2).padLeft(inputs.length, '0'); |
||||
final outputBinary = truthTable[index - 1]; |
||||
|
||||
return TableRow( |
||||
children: inputBinary.runes.map((r) => Text(String.fromCharCodes([r]))) |
||||
.followedBy(outputBinary.runes.map((r) => Text(String.fromCharCodes([r])))) |
||||
.toList(), |
||||
); |
||||
}, |
||||
), |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,240 @@
|
||||
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:logic_circuits_simulator/models/project.dart'; |
||||
import 'package:logic_circuits_simulator/pages/edit_component.dart'; |
||||
import 'package:logic_circuits_simulator/pages_arguments/edit_component.dart'; |
||||
import 'package:logic_circuits_simulator/state/project.dart'; |
||||
import 'package:provider/provider.dart'; |
||||
|
||||
class ProjectPage extends StatelessWidget { |
||||
const ProjectPage({Key? key}) : super(key: key); |
||||
|
||||
static const String routeName = '/project'; |
||||
|
||||
void onComponentDelete(BuildContext context, ComponentEntry c) { |
||||
showDialog( |
||||
context: context, |
||||
builder: (context) { |
||||
return AlertDialog( |
||||
actions: [ |
||||
TextButton( |
||||
onPressed: () => Navigator.of(context).pop(), |
||||
child: const Text('Cancel'), |
||||
), |
||||
ElevatedButton( |
||||
onPressed: () { |
||||
Provider.of<ProjectState>(context, listen: false) |
||||
.deleteComponent(c.componentId); |
||||
Navigator.of(context).pop(); |
||||
}, |
||||
style: ButtonStyle( |
||||
backgroundColor: MaterialStateProperty.all(Colors.red), |
||||
), |
||||
child: const Text('Delete'), |
||||
), |
||||
], |
||||
title: Text('Delete component ${c.componentName}'), |
||||
content: const Text('Are you sure you want to delete the component?'), |
||||
); |
||||
}, |
||||
); |
||||
} |
||||
|
||||
Future<bool> onComponentEdit(BuildContext context, ComponentEntry c, {bool newComponent = false}) { |
||||
return Navigator.of(context).pushNamed( |
||||
EditComponentPage.routeName, |
||||
arguments: EditComponentPageArguments( |
||||
component: c, |
||||
newComponent: newComponent, |
||||
), |
||||
).then((value) => value == true,); |
||||
} |
||||
|
||||
void onComponentCreate(BuildContext context) async { |
||||
final newComponent = await Provider.of<ProjectState>(context, listen: false).newComponent(); |
||||
// ignore: use_build_context_synchronously |
||||
if (!await onComponentEdit(context, newComponent, newComponent: true)) { |
||||
// ignore: use_build_context_synchronously |
||||
await Future.delayed( |
||||
const Duration(milliseconds: 500), |
||||
() => Provider.of<ProjectState>(context, listen: false) |
||||
.deleteComponent(newComponent.componentId), |
||||
); |
||||
} |
||||
} |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
final project = Provider.of<ProjectState>(context).currentProject; |
||||
final index = Provider.of<ProjectState>(context).index; |
||||
|
||||
return WillPopScope( |
||||
onWillPop: () async { |
||||
final ps = Provider.of<ProjectState>(context, listen: false); |
||||
if (ps.needsSaving) { |
||||
Future? saveFuture; |
||||
await showDialog( |
||||
context: context, |
||||
barrierDismissible: false, |
||||
builder: (context) { |
||||
saveFuture ??= ps.saveProject().then((_) { |
||||
Navigator.of(context).pop(); |
||||
}); |
||||
return Center( |
||||
child: Card( |
||||
child: Row( |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: const [ |
||||
Padding( |
||||
padding: EdgeInsets.all(8.0), |
||||
child: CircularProgressIndicator(), |
||||
), |
||||
Padding( |
||||
padding: EdgeInsets.all(8.0), |
||||
child: Text('Saving...'), |
||||
) |
||||
], |
||||
), |
||||
), |
||||
); |
||||
}, |
||||
); |
||||
} |
||||
ps.noProject(); |
||||
return true; |
||||
}, |
||||
child: Scaffold( |
||||
appBar: AppBar( |
||||
title: Text(project?.projectName ?? 'No Project'), |
||||
centerTitle: true, |
||||
), |
||||
body: project == null ? Center( |
||||
child: Column( |
||||
crossAxisAlignment: CrossAxisAlignment.stretch, |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: [ |
||||
Text( |
||||
'No project selected', |
||||
style: Theme.of(context).textTheme.headline4, |
||||
textAlign: TextAlign.center, |
||||
), |
||||
], |
||||
), |
||||
) : CustomScrollView( |
||||
slivers: [ |
||||
SliverPadding( |
||||
padding: const EdgeInsets.all(8), |
||||
sliver: SliverToBoxAdapter( |
||||
child: Row( |
||||
crossAxisAlignment: CrossAxisAlignment.center, |
||||
children: [ |
||||
Expanded( |
||||
child: Text( |
||||
'Components', |
||||
style: Theme.of(context).textTheme.headline5, |
||||
), |
||||
), |
||||
IconButton( |
||||
onPressed: () { |
||||
onComponentCreate(context); |
||||
}, |
||||
icon: const Icon(Icons.add), |
||||
tooltip: 'New Component', |
||||
), |
||||
], |
||||
), |
||||
), |
||||
), |
||||
if (index.components.isNotEmpty) |
||||
SliverToBoxAdapter( |
||||
child: Wrap( |
||||
runSpacing: 8, |
||||
spacing: 8, |
||||
children: index.components.map((c) => IntrinsicWidth( |
||||
child: ComponentCard( |
||||
component: c, |
||||
onComponentDelete: () => onComponentDelete(context, c), |
||||
onComponentEdit: () => onComponentEdit(context, c), |
||||
), |
||||
)).toList(growable: false), |
||||
), |
||||
) |
||||
else |
||||
SliverToBoxAdapter( |
||||
child: Center( |
||||
child: Text( |
||||
'No Components', |
||||
style: Theme.of(context).textTheme.headline6, |
||||
), |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
||||
|
||||
class ComponentCard extends StatelessWidget { |
||||
final ComponentEntry component; |
||||
|
||||
final void Function() onComponentDelete; |
||||
final void Function() onComponentEdit; |
||||
|
||||
const ComponentCard({Key? key, required this.component, required this.onComponentDelete, required this.onComponentEdit}) : super(key: key); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Card( |
||||
child: InkWell( |
||||
onTap: () { |
||||
onComponentEdit(); |
||||
}, |
||||
child: Stack( |
||||
children: [ |
||||
Column( |
||||
children: [ |
||||
Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: Row( |
||||
children: [ |
||||
Expanded( |
||||
child: Text( |
||||
component.componentName, |
||||
style: Theme.of(context).textTheme.headline6, |
||||
), |
||||
), |
||||
const SizedBox(width: 36,), |
||||
], |
||||
), |
||||
), |
||||
], |
||||
), |
||||
Positioned( |
||||
top: 8, |
||||
right: 8, |
||||
child: PopupMenuButton<String>( |
||||
icon: const Icon(Icons.more_horiz), |
||||
itemBuilder: (context) => [ |
||||
const PopupMenuItem( |
||||
value: 'delete', |
||||
child: Text('Delete'), |
||||
), |
||||
], |
||||
onSelected: (selectedOption) { |
||||
switch (selectedOption) { |
||||
case 'delete': |
||||
onComponentDelete(); |
||||
break; |
||||
default: |
||||
throw Exception('Unexpected option: $selectedOption'); |
||||
} |
||||
}, |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,204 @@
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:intl/intl.dart'; |
||||
import 'package:logic_circuits_simulator/dialogs/new_project.dart'; |
||||
import 'package:logic_circuits_simulator/models/projects.dart'; |
||||
import 'package:logic_circuits_simulator/pages/project.dart'; |
||||
import 'package:logic_circuits_simulator/state/project.dart'; |
||||
import 'package:logic_circuits_simulator/state/projects.dart'; |
||||
import 'package:provider/provider.dart'; |
||||
|
||||
class ProjectsPage extends StatelessWidget { |
||||
const ProjectsPage({Key? key}) : super(key: key); |
||||
|
||||
static const String routeName = '/projects'; |
||||
|
||||
void onNewProject(BuildContext context) { |
||||
showDialog( |
||||
context: context, |
||||
builder: (context) { |
||||
return const NewProjectDialog(); |
||||
}, |
||||
); |
||||
} |
||||
|
||||
void onProjectDelete(BuildContext context, ProjectEntry p) { |
||||
showDialog( |
||||
context: context, |
||||
builder: (context) { |
||||
return AlertDialog( |
||||
actions: [ |
||||
TextButton( |
||||
onPressed: () => Navigator.of(context).pop(), |
||||
child: const Text('Cancel'), |
||||
), |
||||
ElevatedButton( |
||||
onPressed: () { |
||||
Provider.of<ProjectsState>(context, listen: false) |
||||
.deleteProject(p.projectId); |
||||
Navigator.of(context).pop(); |
||||
}, |
||||
style: ButtonStyle( |
||||
backgroundColor: MaterialStateProperty.all(Colors.red), |
||||
), |
||||
child: const Text('Delete'), |
||||
), |
||||
], |
||||
title: Text('Delete project ${p.projectName}'), |
||||
content: const Text('Are you sure you want to delete the project?'), |
||||
); |
||||
}, |
||||
); |
||||
} |
||||
|
||||
void onProjectSelect(BuildContext context, ProjectEntry p) { |
||||
Provider.of<ProjectState>(context, listen: false).currentProject = p; |
||||
Provider.of<ProjectState>(context, listen: false).registerSaveHandler((p) async { |
||||
await Provider.of<ProjectsState>(context, listen: false).updateProject(p); |
||||
}); |
||||
Navigator.of(context).pushNamed(ProjectPage.routeName); |
||||
} |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
final projects = Provider.of<ProjectsState>(context).projects; |
||||
|
||||
return Scaffold( |
||||
appBar: AppBar( |
||||
title: const Text('Projects'), |
||||
centerTitle: true, |
||||
), |
||||
body: projects.isNotEmpty |
||||
? SingleChildScrollView( |
||||
child: Wrap( |
||||
runSpacing: 8, |
||||
spacing: 8, |
||||
children: |
||||
projects.map((p) => IntrinsicWidth( |
||||
child: ProjectTile( |
||||
p, |
||||
onProjectDelete: () => onProjectDelete(context, p), |
||||
onProjectExport: () { |
||||
// TODO: Implement project export |
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Export coming soon...'))); |
||||
}, |
||||
onProjectSelect: () => onProjectSelect(context, p), |
||||
), |
||||
)).toList(growable: false), |
||||
), |
||||
) |
||||
: Center( |
||||
child: Column( |
||||
crossAxisAlignment: CrossAxisAlignment.stretch, |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: [ |
||||
Text( |
||||
'No projects', |
||||
style: Theme.of(context).textTheme.headline4, |
||||
textAlign: TextAlign.center, |
||||
), |
||||
const Text.rich( |
||||
TextSpan( |
||||
children: [ |
||||
TextSpan(text: 'Use the '), |
||||
WidgetSpan( |
||||
child: Icon( |
||||
Icons.add, |
||||
size: 16, |
||||
)), |
||||
TextSpan(text: ' button to add a new project.'), |
||||
], |
||||
), |
||||
textAlign: TextAlign.center, |
||||
), |
||||
], |
||||
), |
||||
), |
||||
floatingActionButton: FloatingActionButton( |
||||
onPressed: () => onNewProject(context), |
||||
tooltip: 'New Project', |
||||
child: const Icon(Icons.add), |
||||
), |
||||
); |
||||
} |
||||
} |
||||
|
||||
class ProjectTile extends StatelessWidget { |
||||
final ProjectEntry project; |
||||
final void Function() onProjectSelect; |
||||
final void Function() onProjectDelete; |
||||
final void Function() onProjectExport; |
||||
|
||||
const ProjectTile(this.project, |
||||
{Key? key, required this.onProjectSelect, required this.onProjectDelete, required this.onProjectExport}) |
||||
: super(key: key); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Card( |
||||
child: InkWell( |
||||
onTap: onProjectSelect, |
||||
child: Stack( |
||||
children: [ |
||||
Column( |
||||
crossAxisAlignment: CrossAxisAlignment.stretch, |
||||
children: [ |
||||
Padding( |
||||
padding: const EdgeInsets.all(8.0), |
||||
child: Row( |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: [ |
||||
Expanded( |
||||
child: Text( |
||||
project.projectName, |
||||
style: Theme.of(context).textTheme.headline6, |
||||
), |
||||
), |
||||
const SizedBox(width: 36,), |
||||
], |
||||
), |
||||
), |
||||
Padding( |
||||
padding: const EdgeInsets.all(2.0), |
||||
child: Text( |
||||
DateFormat.yMMMd().add_jms().format(project.lastUpdate.toLocal()), |
||||
style: Theme.of(context).textTheme.caption, |
||||
textAlign: TextAlign.end, |
||||
), |
||||
), |
||||
], |
||||
), |
||||
Positioned( |
||||
top: 8, |
||||
right: 8, |
||||
child: PopupMenuButton<String>( |
||||
icon: const Icon(Icons.more_horiz), |
||||
itemBuilder: (context) => [ |
||||
const PopupMenuItem( |
||||
value: 'export', |
||||
child: Text('Export'), |
||||
), |
||||
const PopupMenuItem( |
||||
value: 'delete', |
||||
child: Text('Delete'), |
||||
), |
||||
], |
||||
onSelected: (selectedOption) { |
||||
switch (selectedOption) { |
||||
case 'delete': |
||||
onProjectDelete(); |
||||
break; |
||||
case 'export': |
||||
onProjectExport(); |
||||
break; |
||||
default: |
||||
throw Exception('Unexpected option: $selectedOption'); |
||||
} |
||||
}, |
||||
), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,17 @@
|
||||
import 'package:flutter/material.dart'; |
||||
|
||||
class SettingsPage extends StatelessWidget { |
||||
const SettingsPage({Key? key}) : super(key: key); |
||||
|
||||
static const String routeName = '/settings'; |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Scaffold( |
||||
appBar: AppBar( |
||||
title: const Text('Settings'), |
||||
centerTitle: true, |
||||
), |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart'; |
||||
import 'package:logic_circuits_simulator/models/project.dart'; |
||||
|
||||
part 'edit_component.freezed.dart'; |
||||
|
||||
@freezed |
||||
class EditComponentPageArguments with _$EditComponentPageArguments { |
||||
const factory EditComponentPageArguments({ |
||||
required ComponentEntry component, |
||||
@Default(false) |
||||
bool newComponent, |
||||
}) = _EditComponentPageArguments; |
||||
} |
@ -0,0 +1,170 @@
|
||||
// coverage:ignore-file |
||||
// GENERATED CODE - DO NOT MODIFY BY HAND |
||||
// ignore_for_file: type=lint |
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target |
||||
|
||||
part of 'edit_component.dart'; |
||||
|
||||
// ************************************************************************** |
||||
// FreezedGenerator |
||||
// ************************************************************************** |
||||
|
||||
T _$identity<T>(T value) => value; |
||||
|
||||
final _privateConstructorUsedError = UnsupportedError( |
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); |
||||
|
||||
/// @nodoc |
||||
mixin _$EditComponentPageArguments { |
||||
ComponentEntry get component => throw _privateConstructorUsedError; |
||||
bool get newComponent => throw _privateConstructorUsedError; |
||||
|
||||
@JsonKey(ignore: true) |
||||
$EditComponentPageArgumentsCopyWith<EditComponentPageArguments> |
||||
get copyWith => throw _privateConstructorUsedError; |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class $EditComponentPageArgumentsCopyWith<$Res> { |
||||
factory $EditComponentPageArgumentsCopyWith(EditComponentPageArguments value, |
||||
$Res Function(EditComponentPageArguments) then) = |
||||
_$EditComponentPageArgumentsCopyWithImpl<$Res>; |
||||
$Res call({ComponentEntry component, bool newComponent}); |
||||
|
||||
$ComponentEntryCopyWith<$Res> get component; |
||||
} |
||||
|
||||
/// @nodoc |
||||
class _$EditComponentPageArgumentsCopyWithImpl<$Res> |
||||
implements $EditComponentPageArgumentsCopyWith<$Res> { |
||||
_$EditComponentPageArgumentsCopyWithImpl(this._value, this._then); |
||||
|
||||
final EditComponentPageArguments _value; |
||||
// ignore: unused_field |
||||
final $Res Function(EditComponentPageArguments) _then; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? component = freezed, |
||||
Object? newComponent = freezed, |
||||
}) { |
||||
return _then(_value.copyWith( |
||||
component: component == freezed |
||||
? _value.component |
||||
: component // ignore: cast_nullable_to_non_nullable |
||||
as ComponentEntry, |
||||
newComponent: newComponent == freezed |
||||
? _value.newComponent |
||||
: newComponent // ignore: cast_nullable_to_non_nullable |
||||
as bool, |
||||
)); |
||||
} |
||||
|
||||
@override |
||||
$ComponentEntryCopyWith<$Res> get component { |
||||
return $ComponentEntryCopyWith<$Res>(_value.component, (value) { |
||||
return _then(_value.copyWith(component: value)); |
||||
}); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
abstract class _$$_EditComponentPageArgumentsCopyWith<$Res> |
||||
implements $EditComponentPageArgumentsCopyWith<$Res> { |
||||
factory _$$_EditComponentPageArgumentsCopyWith( |
||||
_$_EditComponentPageArguments value, |
||||
$Res Function(_$_EditComponentPageArguments) then) = |
||||
__$$_EditComponentPageArgumentsCopyWithImpl<$Res>; |
||||
@override |
||||
$Res call({ComponentEntry component, bool newComponent}); |
||||
|
||||
@override |
||||
$ComponentEntryCopyWith<$Res> get component; |
||||
} |
||||
|
||||
/// @nodoc |
||||
class __$$_EditComponentPageArgumentsCopyWithImpl<$Res> |
||||
extends _$EditComponentPageArgumentsCopyWithImpl<$Res> |
||||
implements _$$_EditComponentPageArgumentsCopyWith<$Res> { |
||||
__$$_EditComponentPageArgumentsCopyWithImpl( |
||||
_$_EditComponentPageArguments _value, |
||||
$Res Function(_$_EditComponentPageArguments) _then) |
||||
: super(_value, (v) => _then(v as _$_EditComponentPageArguments)); |
||||
|
||||
@override |
||||
_$_EditComponentPageArguments get _value => |
||||
super._value as _$_EditComponentPageArguments; |
||||
|
||||
@override |
||||
$Res call({ |
||||
Object? component = freezed, |
||||
Object? newComponent = freezed, |
||||
}) { |
||||
return _then(_$_EditComponentPageArguments( |
||||
component: component == freezed |
||||
? _value.component |
||||
: component // ignore: cast_nullable_to_non_nullable |
||||
as ComponentEntry, |
||||
newComponent: newComponent == freezed |
||||
? _value.newComponent |
||||
: newComponent // ignore: cast_nullable_to_non_nullable |
||||
as bool, |
||||
)); |
||||
} |
||||
} |
||||
|
||||
/// @nodoc |
||||
|
||||
class _$_EditComponentPageArguments implements _EditComponentPageArguments { |
||||
const _$_EditComponentPageArguments( |
||||
{required this.component, this.newComponent = false}); |
||||
|
||||
@override |
||||
final ComponentEntry component; |
||||
@override |
||||
@JsonKey() |
||||
final bool newComponent; |
||||
|
||||
@override |
||||
String toString() { |
||||
return 'EditComponentPageArguments(component: $component, newComponent: $newComponent)'; |
||||
} |
||||
|
||||
@override |
||||
bool operator ==(dynamic other) { |
||||
return identical(this, other) || |
||||
(other.runtimeType == runtimeType && |
||||
other is _$_EditComponentPageArguments && |
||||
const DeepCollectionEquality().equals(other.component, component) && |
||||
const DeepCollectionEquality() |
||||
.equals(other.newComponent, newComponent)); |
||||
} |
||||
|
||||
@override |
||||
int get hashCode => Object.hash( |
||||
runtimeType, |
||||
const DeepCollectionEquality().hash(component), |
||||
const DeepCollectionEquality().hash(newComponent)); |
||||
|
||||
@JsonKey(ignore: true) |
||||
@override |
||||
_$$_EditComponentPageArgumentsCopyWith<_$_EditComponentPageArguments> |
||||
get copyWith => __$$_EditComponentPageArgumentsCopyWithImpl< |
||||
_$_EditComponentPageArguments>(this, _$identity); |
||||
} |
||||
|
||||
abstract class _EditComponentPageArguments |
||||
implements EditComponentPageArguments { |
||||
const factory _EditComponentPageArguments( |
||||
{required final ComponentEntry component, |
||||
final bool newComponent}) = _$_EditComponentPageArguments; |
||||
|
||||
@override |
||||
ComponentEntry get component => throw _privateConstructorUsedError; |
||||
@override |
||||
bool get newComponent => throw _privateConstructorUsedError; |
||||
@override |
||||
@JsonKey(ignore: true) |
||||
_$$_EditComponentPageArgumentsCopyWith<_$_EditComponentPageArguments> |
||||
get copyWith => throw _privateConstructorUsedError; |
||||
} |
@ -0,0 +1,109 @@
|
||||
import 'dart:convert'; |
||||
import 'dart:io'; |
||||
|
||||
import 'package:flutter/foundation.dart'; |
||||
import 'package:logic_circuits_simulator/models/project.dart'; |
||||
import 'package:logic_circuits_simulator/models/projects.dart'; |
||||
import 'package:path_provider/path_provider.dart'; |
||||
import 'package:path/path.dart' as path; |
||||
import 'package:uuid/uuid.dart'; |
||||
|
||||
class ProjectState extends ChangeNotifier { |
||||
bool _dirty = false; |
||||
final List<Future Function(ProjectEntry)> _saveHandlers = []; |
||||
|
||||
ProjectEntry? _currentProject; |
||||
ProjectIndex _index = const ProjectIndex(components: []); |
||||
|
||||
ProjectEntry? get currentProject => _currentProject; |
||||
ProjectIndex get index => _index; |
||||
bool get needsSaving => currentProject != null && _dirty; |
||||
|
||||
Future<Directory> _getProjectDir() async { |
||||
if (_currentProject == null) { |
||||
throw Exception('Cannot get project directory of null'); |
||||
} |
||||
final appDir = await getApplicationDocumentsDirectory(); |
||||
final result = Directory(path.join(appDir.path, 'LogicCircuitsSimulator', 'projects', _currentProject!.projectId)); |
||||
if (!await result.exists()) { |
||||
await result.create(recursive: true); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
Future<File> _getIndexFile() async { |
||||
final result = File(path.join((await _getProjectDir()).path, 'index.json')); |
||||
return result; |
||||
} |
||||
|
||||
Future<void> _loadProjectFiles() async { |
||||
final indexFile = await _getIndexFile(); |
||||
if (!await indexFile.exists()) { |
||||
_index = const ProjectIndex(components: []); |
||||
await indexFile.writeAsString(jsonEncode(_index.toJson())); |
||||
} |
||||
else { |
||||
_index = ProjectIndex.fromJson(jsonDecode(await indexFile.readAsString())); |
||||
} |
||||
} |
||||
|
||||
Future<void> _updateIndex(ProjectIndex newIndex) async { |
||||
_dirty = true; |
||||
_index = newIndex; |
||||
final indexFile = await _getIndexFile(); |
||||
await indexFile.writeAsString(jsonEncode(index.toJson())); |
||||
notifyListeners(); |
||||
} |
||||
|
||||
set currentProject(ProjectEntry? p) { |
||||
_currentProject = p; |
||||
_loadProjectFiles().then((_) => notifyListeners()); |
||||
} |
||||
|
||||
void noProject() { |
||||
_currentProject = null; |
||||
_index = const ProjectIndex(components: []); |
||||
notifyListeners(); |
||||
} |
||||
|
||||
Future<void> deleteComponent(String componentId) async { |
||||
await _updateIndex(index.copyWith(components: index.components.where((c) => c.componentId != componentId).toList())); |
||||
} |
||||
|
||||
Future<ComponentEntry> newComponent() async { |
||||
final newComponent = ComponentEntry( |
||||
componentId: const Uuid().v4(), |
||||
componentName: '', |
||||
inputs: [], |
||||
outputs: [], |
||||
); |
||||
await _updateIndex(index.copyWith(components: index.components + [newComponent])); |
||||
return newComponent; |
||||
} |
||||
|
||||
Future<void> editComponent(ComponentEntry component) async { |
||||
if (!index.components.map((c) => c.componentId).contains(component.componentId)) { |
||||
throw Exception('Component not in index!'); |
||||
} |
||||
await _updateIndex( |
||||
index.copyWith( |
||||
components: index.components |
||||
.where((c) => c.componentId != component.componentId) |
||||
.toList() + [component], |
||||
) |
||||
); |
||||
} |
||||
|
||||
Future<void> saveProject() async { |
||||
if (!needsSaving) return; |
||||
_currentProject = currentProject?.copyWith(lastUpdate: DateTime.now()); |
||||
await Future.wait(_saveHandlers.map((h) => h(_currentProject!))); |
||||
_saveHandlers.clear(); |
||||
_dirty = false; |
||||
notifyListeners(); |
||||
} |
||||
|
||||
void registerSaveHandler(Future Function(ProjectEntry) handler) { |
||||
_saveHandlers.add(handler); |
||||
} |
||||
} |
@ -0,0 +1,80 @@
|
||||
import 'dart:convert'; |
||||
import 'dart:io'; |
||||
|
||||
import 'package:flutter/foundation.dart'; |
||||
import 'package:logic_circuits_simulator/models/projects.dart'; |
||||
import 'package:path_provider/path_provider.dart'; |
||||
import 'package:path/path.dart' as path; |
||||
import 'package:uuid/uuid.dart'; |
||||
|
||||
class ProjectsState extends ChangeNotifier { |
||||
ProjectsState() { |
||||
_init(); |
||||
} |
||||
|
||||
List<ProjectEntry> get projects => index.projects; |
||||
ProjectsIndex index = const ProjectsIndex(projects: []); |
||||
|
||||
Future<Directory> _getProjectsDir() async { |
||||
final appDir = await getApplicationDocumentsDirectory(); |
||||
final result = Directory(path.join(appDir.path, 'LogicCircuitsSimulator', 'projects')); |
||||
if (!await result.exists()) { |
||||
await result.create(recursive: true); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
Future<File> _getIndexFile() async { |
||||
final result = File(path.join((await _getProjectsDir()).path, 'index.json')); |
||||
return result; |
||||
} |
||||
|
||||
Future<void> _updateIndex(ProjectsIndex newIndex) async { |
||||
// Sort projects when updating: latest update first |
||||
index = newIndex.copyWith(projects: newIndex.projects.toList()..sort((p1, p2) => p2.lastUpdate.compareTo(p1.lastUpdate))); |
||||
final indexFile = await _getIndexFile(); |
||||
await indexFile.writeAsString(jsonEncode(index.toJson())); |
||||
notifyListeners(); |
||||
} |
||||
|
||||
void _init() async { |
||||
final indexFile = await _getIndexFile(); |
||||
if (await indexFile.exists()) { |
||||
index = ProjectsIndex.fromJson(jsonDecode(await indexFile.readAsString())); |
||||
notifyListeners(); |
||||
} |
||||
} |
||||
|
||||
Future<void> newProject(String projectName) async { |
||||
final id = const Uuid().v4(); |
||||
final project = ProjectEntry( |
||||
lastUpdate: DateTime.now(), |
||||
projectName: projectName, |
||||
projectId: id, |
||||
); |
||||
await _updateIndex(index.copyWith(projects: index.projects + [project])); |
||||
final projectDir = await Directory(path.join((await _getProjectsDir()).path, id)).create(); |
||||
await Directory(path.join(projectDir.path, 'components')).create(); |
||||
if (kDebugMode) { |
||||
print('Created new project in ${projectDir.path}'); |
||||
} |
||||
} |
||||
|
||||
Future<void> deleteProject(String projectId) async { |
||||
await _updateIndex(index.copyWith(projects: index.projects.where((p) => p.projectId != projectId).toList())); |
||||
await Directory(path.join((await _getProjectsDir()).path, projectId)).delete(recursive: true); |
||||
} |
||||
|
||||
Future<void> updateProject(ProjectEntry project) async { |
||||
if (!index.projects.map((p) => p.projectId).contains(project.projectId)) { |
||||
throw Exception('Project not in index!'); |
||||
} |
||||
await _updateIndex( |
||||
index.copyWith( |
||||
projects: index.projects |
||||
.where((p) => p.projectId != project.projectId) |
||||
.toList() + [project] |
||||
) |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,7 @@
|
||||
import 'package:flutter_hooks/flutter_hooks.dart'; |
||||
import 'package:provider/provider.dart'; |
||||
|
||||
T useProvider<T>() { |
||||
final context = useContext(); |
||||
return Provider.of<T>(context); |
||||
} |
@ -0,0 +1,138 @@
|
||||
# Project-level configuration. |
||||
cmake_minimum_required(VERSION 3.10) |
||||
project(runner LANGUAGES CXX) |
||||
|
||||
# The name of the executable created for the application. Change this to change |
||||
# the on-disk name of your application. |
||||
set(BINARY_NAME "logic_circuits_simulator") |
||||
# The unique GTK application identifier for this application. See: |
||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID |
||||
set(APPLICATION_ID "ro.dcdev.logic_circuits_simulator") |
||||
|
||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent |
||||
# versions of CMake. |
||||
cmake_policy(SET CMP0063 NEW) |
||||
|
||||
# Load bundled libraries from the lib/ directory relative to the binary. |
||||
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") |
||||
|
||||
# Root filesystem for cross-building. |
||||
if(FLUTTER_TARGET_PLATFORM_SYSROOT) |
||||
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) |
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) |
||||
endif() |
||||
|
||||
# Define build configuration options. |
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) |
||||
set(CMAKE_BUILD_TYPE "Debug" CACHE |
||||
STRING "Flutter build mode" FORCE) |
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS |
||||
"Debug" "Profile" "Release") |
||||
endif() |
||||
|
||||
# Compilation settings that should be applied to most targets. |
||||
# |
||||
# Be cautious about adding new options here, as plugins use this function by |
||||
# default. In most cases, you should add new options to specific targets instead |
||||
# of modifying this function. |
||||
function(APPLY_STANDARD_SETTINGS TARGET) |
||||
target_compile_features(${TARGET} PUBLIC cxx_std_14) |
||||
target_compile_options(${TARGET} PRIVATE -Wall -Werror) |
||||
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>") |
||||
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>") |
||||
endfunction() |
||||
|
||||
# Flutter library and tool build rules. |
||||
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") |
||||
add_subdirectory(${FLUTTER_MANAGED_DIR}) |
||||
|
||||
# System-level dependencies. |
||||
find_package(PkgConfig REQUIRED) |
||||
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) |
||||
|
||||
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") |
||||
|
||||
# Define the application target. To change its name, change BINARY_NAME above, |
||||
# not the value here, or `flutter run` will no longer work. |
||||
# |
||||
# Any new source files that you add to the application should be added here. |
||||
add_executable(${BINARY_NAME} |
||||
"main.cc" |
||||
"my_application.cc" |
||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" |
||||
) |
||||
|
||||
# Apply the standard set of build settings. This can be removed for applications |
||||
# that need different build settings. |
||||
apply_standard_settings(${BINARY_NAME}) |
||||
|
||||
# Add dependency libraries. Add any application-specific dependencies here. |
||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter) |
||||
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) |
||||
|
||||
# Run the Flutter tool portions of the build. This must not be removed. |
||||
add_dependencies(${BINARY_NAME} flutter_assemble) |
||||
|
||||
# Only the install-generated bundle's copy of the executable will launch |
||||
# correctly, since the resources must in the right relative locations. To avoid |
||||
# people trying to run the unbundled copy, put it in a subdirectory instead of |
||||
# the default top-level location. |
||||
set_target_properties(${BINARY_NAME} |
||||
PROPERTIES |
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" |
||||
) |
||||
|
||||
# Generated plugin build rules, which manage building the plugins and adding |
||||
# them to the application. |
||||
include(flutter/generated_plugins.cmake) |
||||
|
||||
|
||||
# === Installation === |
||||
# By default, "installing" just makes a relocatable bundle in the build |
||||
# directory. |
||||
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") |
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) |
||||
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) |
||||
endif() |
||||
|
||||
# Start with a clean build bundle directory every time. |
||||
install(CODE " |
||||
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") |
||||
" COMPONENT Runtime) |
||||
|
||||
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") |
||||
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") |
||||
|
||||
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" |
||||
COMPONENT Runtime) |
||||
|
||||
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" |
||||
COMPONENT Runtime) |
||||
|
||||
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" |
||||
COMPONENT Runtime) |
||||
|
||||
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) |
||||
install(FILES "${bundled_library}" |
||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" |
||||
COMPONENT Runtime) |
||||
endforeach(bundled_library) |
||||
|
||||
# Fully re-copy the assets directory on each build to avoid having stale files |
||||
# from a previous install. |
||||
set(FLUTTER_ASSET_DIR_NAME "flutter_assets") |
||||
install(CODE " |
||||
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") |
||||
" COMPONENT Runtime) |
||||
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" |
||||
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) |
||||
|
||||
# Install the AOT library on non-Debug builds only. |
||||
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") |
||||
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" |
||||
COMPONENT Runtime) |
||||
endif() |
@ -0,0 +1,88 @@
|
||||
# This file controls Flutter-level build steps. It should not be edited. |
||||
cmake_minimum_required(VERSION 3.10) |
||||
|
||||
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") |
||||
|
||||
# Configuration provided via flutter tool. |
||||
include(${EPHEMERAL_DIR}/generated_config.cmake) |
||||
|
||||
# TODO: Move the rest of this into files in ephemeral. See |
||||
# https://github.com/flutter/flutter/issues/57146. |
||||
|
||||
# Serves the same purpose as list(TRANSFORM ... PREPEND ...), |
||||
# which isn't available in 3.10. |
||||
function(list_prepend LIST_NAME PREFIX) |
||||
set(NEW_LIST "") |
||||
foreach(element ${${LIST_NAME}}) |
||||
list(APPEND NEW_LIST "${PREFIX}${element}") |
||||
endforeach(element) |
||||
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) |
||||
endfunction() |
||||
|
||||
# === Flutter Library === |
||||
# System-level dependencies. |
||||
find_package(PkgConfig REQUIRED) |
||||
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) |
||||
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) |
||||
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) |
||||
|
||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") |
||||
|
||||
# Published to parent scope for install step. |
||||
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) |
||||
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) |
||||
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) |
||||
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) |
||||
|
||||
list(APPEND FLUTTER_LIBRARY_HEADERS |
||||
"fl_basic_message_channel.h" |
||||
"fl_binary_codec.h" |
||||
"fl_binary_messenger.h" |
||||
"fl_dart_project.h" |
||||
"fl_engine.h" |
||||
"fl_json_message_codec.h" |
||||
"fl_json_method_codec.h" |
||||
"fl_message_codec.h" |
||||
"fl_method_call.h" |
||||
"fl_method_channel.h" |
||||
"fl_method_codec.h" |
||||
"fl_method_response.h" |
||||
"fl_plugin_registrar.h" |
||||
"fl_plugin_registry.h" |
||||
"fl_standard_message_codec.h" |
||||
"fl_standard_method_codec.h" |
||||
"fl_string_codec.h" |
||||
"fl_value.h" |
||||
"fl_view.h" |
||||
"flutter_linux.h" |
||||
) |
||||
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") |
||||
add_library(flutter INTERFACE) |
||||
target_include_directories(flutter INTERFACE |
||||
"${EPHEMERAL_DIR}" |
||||
) |
||||
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") |
||||
target_link_libraries(flutter INTERFACE |
||||
PkgConfig::GTK |
||||
PkgConfig::GLIB |
||||
PkgConfig::GIO |
||||
) |
||||
add_dependencies(flutter flutter_assemble) |
||||
|
||||
# === Flutter tool backend === |
||||
# _phony_ is a non-existent file to force this command to run every time, |
||||
# since currently there's no way to get a full input/output list from the |
||||
# flutter tool. |
||||
add_custom_command( |
||||
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} |
||||
${CMAKE_CURRENT_BINARY_DIR}/_phony_ |
||||
COMMAND ${CMAKE_COMMAND} -E env |
||||
${FLUTTER_TOOL_ENVIRONMENT} |
||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" |
||||
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} |
||||
VERBATIM |
||||
) |
||||
add_custom_target(flutter_assemble DEPENDS |
||||
"${FLUTTER_LIBRARY}" |
||||
${FLUTTER_LIBRARY_HEADERS} |
||||
) |
@ -0,0 +1,11 @@
|
||||
//
|
||||
// Generated file. Do not edit.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include "generated_plugin_registrant.h" |
||||
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) { |
||||
} |
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Generated file. Do not edit.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef GENERATED_PLUGIN_REGISTRANT_ |
||||
#define GENERATED_PLUGIN_REGISTRANT_ |
||||
|
||||
#include <flutter_linux/flutter_linux.h> |
||||
|
||||
// Registers Flutter plugins.
|
||||
void fl_register_plugins(FlPluginRegistry* registry); |
||||
|
||||
#endif // GENERATED_PLUGIN_REGISTRANT_
|
@ -0,0 +1,23 @@
|
||||
# |
||||
# Generated file, do not edit. |
||||
# |
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST |
||||
) |
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST |
||||
) |
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES) |
||||
|
||||
foreach(plugin ${FLUTTER_PLUGIN_LIST}) |
||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) |
||||
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) |
||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>) |
||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) |
||||
endforeach(plugin) |
||||
|
||||
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) |
||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) |
||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) |
||||
endforeach(ffi_plugin) |
@ -0,0 +1,6 @@
|
||||
#include "my_application.h" |
||||
|
||||
int main(int argc, char** argv) { |
||||
g_autoptr(MyApplication) app = my_application_new(); |
||||
return g_application_run(G_APPLICATION(app), argc, argv); |
||||
} |
@ -0,0 +1,104 @@
|
||||
#include "my_application.h" |
||||
|
||||
#include <flutter_linux/flutter_linux.h> |
||||
#ifdef GDK_WINDOWING_X11 |
||||
#include <gdk/gdkx.h> |
||||
#endif |
||||
|
||||
#include "flutter/generated_plugin_registrant.h" |
||||
|
||||
struct _MyApplication { |
||||
GtkApplication parent_instance; |
||||
char** dart_entrypoint_arguments; |
||||
}; |
||||
|
||||
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) |
||||
|
||||
// Implements GApplication::activate.
|
||||
static void my_application_activate(GApplication* application) { |
||||
MyApplication* self = MY_APPLICATION(application); |
||||
GtkWindow* window = |
||||
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); |
||||
|
||||
// Use a header bar when running in GNOME as this is the common style used
|
||||
// by applications and is the setup most users will be using (e.g. Ubuntu
|
||||
// desktop).
|
||||
// If running on X and not using GNOME then just use a traditional title bar
|
||||
// in case the window manager does more exotic layout, e.g. tiling.
|
||||
// If running on Wayland assume the header bar will work (may need changing
|
||||
// if future cases occur).
|
||||
gboolean use_header_bar = TRUE; |
||||
#ifdef GDK_WINDOWING_X11 |
||||
GdkScreen* screen = gtk_window_get_screen(window); |
||||
if (GDK_IS_X11_SCREEN(screen)) { |
||||
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); |
||||
if (g_strcmp0(wm_name, "GNOME Shell") != 0) { |
||||
use_header_bar = FALSE; |
||||
} |
||||
} |
||||
#endif |
||||
if (use_header_bar) { |
||||
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); |
||||
gtk_widget_show(GTK_WIDGET(header_bar)); |
||||
gtk_header_bar_set_title(header_bar, "logic_circuits_simulator"); |
||||
gtk_header_bar_set_show_close_button(header_bar, TRUE); |
||||
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); |
||||
} else { |
||||
gtk_window_set_title(window, "logic_circuits_simulator"); |
||||
} |
||||
|
||||
gtk_window_set_default_size(window, 1280, 720); |
||||
gtk_widget_show(GTK_WIDGET(window)); |
||||
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new(); |
||||
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); |
||||
|
||||
FlView* view = fl_view_new(project); |
||||
gtk_widget_show(GTK_WIDGET(view)); |
||||
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); |
||||
|
||||
fl_register_plugins(FL_PLUGIN_REGISTRY(view)); |
||||
|
||||
gtk_widget_grab_focus(GTK_WIDGET(view)); |
||||
} |
||||
|
||||
// Implements GApplication::local_command_line.
|
||||
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { |
||||
MyApplication* self = MY_APPLICATION(application); |
||||
// Strip out the first argument as it is the binary name.
|
||||
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); |
||||
|
||||
g_autoptr(GError) error = nullptr; |
||||
if (!g_application_register(application, nullptr, &error)) { |
||||
g_warning("Failed to register: %s", error->message); |
||||
*exit_status = 1; |
||||
return TRUE; |
||||
} |
||||
|
||||
g_application_activate(application); |
||||
*exit_status = 0; |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
// Implements GObject::dispose.
|
||||
static void my_application_dispose(GObject* object) { |
||||
MyApplication* self = MY_APPLICATION(object); |
||||
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); |
||||
G_OBJECT_CLASS(my_application_parent_class)->dispose(object); |
||||
} |
||||
|
||||
static void my_application_class_init(MyApplicationClass* klass) { |
||||
G_APPLICATION_CLASS(klass)->activate = my_application_activate; |
||||
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; |
||||
G_OBJECT_CLASS(klass)->dispose = my_application_dispose; |
||||
} |
||||
|
||||
static void my_application_init(MyApplication* self) {} |
||||
|
||||
MyApplication* my_application_new() { |
||||
return MY_APPLICATION(g_object_new(my_application_get_type(), |
||||
"application-id", APPLICATION_ID, |
||||
"flags", G_APPLICATION_NON_UNIQUE, |
||||
nullptr)); |
||||
} |
@ -0,0 +1,18 @@
|
||||
#ifndef FLUTTER_MY_APPLICATION_H_ |
||||
#define FLUTTER_MY_APPLICATION_H_ |
||||
|
||||
#include <gtk/gtk.h> |
||||
|
||||
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, |
||||
GtkApplication) |
||||
|
||||
/**
|
||||
* my_application_new: |
||||
* |
||||
* Creates a new Flutter-based application. |
||||
* |
||||
* Returns: a new #MyApplication. |
||||
*/ |
||||
MyApplication* my_application_new(); |
||||
|
||||
#endif // FLUTTER_MY_APPLICATION_H_
|
@ -0,0 +1,670 @@
|
||||
# Generated by pub |
||||
# See https://dart.dev/tools/pub/glossary#lockfile |
||||
packages: |
||||
_fe_analyzer_shared: |
||||
dependency: transitive |
||||
description: |
||||
name: _fe_analyzer_shared |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "39.0.0" |
||||
analyzer: |
||||
dependency: transitive |
||||
description: |
||||
name: analyzer |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "4.0.0" |
||||
args: |
||||
dependency: transitive |
||||
description: |
||||
name: args |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.3.0" |
||||
async: |
||||
dependency: transitive |
||||
description: |
||||
name: async |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.8.2" |
||||
boolean_selector: |
||||
dependency: transitive |
||||
description: |
||||
name: boolean_selector |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.0" |
||||
build: |
||||
dependency: transitive |
||||
description: |
||||
name: build |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.3.0" |
||||
build_config: |
||||
dependency: transitive |
||||
description: |
||||
name: build_config |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.0" |
||||
build_daemon: |
||||
dependency: transitive |
||||
description: |
||||
name: build_daemon |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "3.1.0" |
||||
build_resolvers: |
||||
dependency: transitive |
||||
description: |
||||
name: build_resolvers |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.8" |
||||
build_runner: |
||||
dependency: "direct dev" |
||||
description: |
||||
name: build_runner |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.10" |
||||
build_runner_core: |
||||
dependency: transitive |
||||
description: |
||||
name: build_runner_core |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "7.2.3" |
||||
built_collection: |
||||
dependency: transitive |
||||
description: |
||||
name: built_collection |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "5.1.1" |
||||
built_value: |
||||
dependency: transitive |
||||
description: |
||||
name: built_value |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "8.2.3" |
||||
characters: |
||||
dependency: transitive |
||||
description: |
||||
name: characters |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.2.0" |
||||
charcode: |
||||
dependency: transitive |
||||
description: |
||||
name: charcode |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.3.1" |
||||
checked_yaml: |
||||
dependency: transitive |
||||
description: |
||||
name: checked_yaml |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.1" |
||||
clock: |
||||
dependency: transitive |
||||
description: |
||||
name: clock |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.1.0" |
||||
code_builder: |
||||
dependency: transitive |
||||
description: |
||||
name: code_builder |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "4.1.0" |
||||
collection: |
||||
dependency: transitive |
||||
description: |
||||
name: collection |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.16.0" |
||||
convert: |
||||
dependency: transitive |
||||
description: |
||||
name: convert |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "3.0.1" |
||||
crypto: |
||||
dependency: transitive |
||||
description: |
||||
name: crypto |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "3.0.2" |
||||
cupertino_icons: |
||||
dependency: "direct main" |
||||
description: |
||||
name: cupertino_icons |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.4" |
||||
dart_style: |
||||
dependency: transitive |
||||
description: |
||||
name: dart_style |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.2.3" |
||||
fake_async: |
||||
dependency: transitive |
||||
description: |
||||
name: fake_async |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.3.0" |
||||
ffi: |
||||
dependency: transitive |
||||
description: |
||||
name: ffi |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.1.2" |
||||
file: |
||||
dependency: transitive |
||||
description: |
||||
name: file |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "6.1.2" |
||||
fixnum: |
||||
dependency: transitive |
||||
description: |
||||
name: fixnum |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.0" |
||||
flutter: |
||||
dependency: "direct main" |
||||
description: flutter |
||||
source: sdk |
||||
version: "0.0.0" |
||||
flutter_hooks: |
||||
dependency: "direct main" |
||||
description: |
||||
name: flutter_hooks |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "0.18.3" |
||||
flutter_lints: |
||||
dependency: "direct dev" |
||||
description: |
||||
name: flutter_lints |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.0" |
||||
flutter_test: |
||||
dependency: "direct dev" |
||||
description: flutter |
||||
source: sdk |
||||
version: "0.0.0" |
||||
flutter_web_plugins: |
||||
dependency: transitive |
||||
description: flutter |
||||
source: sdk |
||||
version: "0.0.0" |
||||
freezed: |
||||
dependency: "direct main" |
||||
description: |
||||
name: freezed |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.3" |
||||
freezed_annotation: |
||||
dependency: "direct main" |
||||
description: |
||||
name: freezed_annotation |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.3" |
||||
frontend_server_client: |
||||
dependency: transitive |
||||
description: |
||||
name: frontend_server_client |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.2" |
||||
glob: |
||||
dependency: transitive |
||||
description: |
||||
name: glob |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.2" |
||||
graphs: |
||||
dependency: transitive |
||||
description: |
||||
name: graphs |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.0" |
||||
http_multi_server: |
||||
dependency: transitive |
||||
description: |
||||
name: http_multi_server |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "3.2.0" |
||||
http_parser: |
||||
dependency: transitive |
||||
description: |
||||
name: http_parser |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "4.0.0" |
||||
intl: |
||||
dependency: "direct main" |
||||
description: |
||||
name: intl |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "0.17.0" |
||||
io: |
||||
dependency: transitive |
||||
description: |
||||
name: io |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.3" |
||||
js: |
||||
dependency: transitive |
||||
description: |
||||
name: js |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "0.6.4" |
||||
json_annotation: |
||||
dependency: "direct main" |
||||
description: |
||||
name: json_annotation |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "4.5.0" |
||||
json_serializable: |
||||
dependency: "direct dev" |
||||
description: |
||||
name: json_serializable |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "6.2.0" |
||||
lints: |
||||
dependency: transitive |
||||
description: |
||||
name: lints |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.0" |
||||
logging: |
||||
dependency: transitive |
||||
description: |
||||
name: logging |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.2" |
||||
matcher: |
||||
dependency: transitive |
||||
description: |
||||
name: matcher |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "0.12.11" |
||||
material_color_utilities: |
||||
dependency: transitive |
||||
description: |
||||
name: material_color_utilities |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "0.1.4" |
||||
meta: |
||||
dependency: transitive |
||||
description: |
||||
name: meta |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.7.0" |
||||
mime: |
||||
dependency: transitive |
||||
description: |
||||
name: mime |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.2" |
||||
nested: |
||||
dependency: transitive |
||||
description: |
||||
name: nested |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.0" |
||||
package_config: |
||||
dependency: transitive |
||||
description: |
||||
name: package_config |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.2" |
||||
path: |
||||
dependency: "direct main" |
||||
description: |
||||
name: path |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.8.1" |
||||
path_provider: |
||||
dependency: "direct main" |
||||
description: |
||||
name: path_provider |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.9" |
||||
path_provider_android: |
||||
dependency: transitive |
||||
description: |
||||
name: path_provider_android |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.13" |
||||
path_provider_ios: |
||||
dependency: transitive |
||||
description: |
||||
name: path_provider_ios |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.8" |
||||
path_provider_linux: |
||||
dependency: transitive |
||||
description: |
||||
name: path_provider_linux |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.5" |
||||
path_provider_macos: |
||||
dependency: transitive |
||||
description: |
||||
name: path_provider_macos |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.5" |
||||
path_provider_platform_interface: |
||||
dependency: transitive |
||||
description: |
||||
name: path_provider_platform_interface |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.3" |
||||
path_provider_windows: |
||||
dependency: transitive |
||||
description: |
||||
name: path_provider_windows |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.5" |
||||
platform: |
||||
dependency: transitive |
||||
description: |
||||
name: platform |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "3.1.0" |
||||
plugin_platform_interface: |
||||
dependency: transitive |
||||
description: |
||||
name: plugin_platform_interface |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.2" |
||||
pool: |
||||
dependency: transitive |
||||
description: |
||||
name: pool |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.5.0" |
||||
process: |
||||
dependency: transitive |
||||
description: |
||||
name: process |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "4.2.4" |
||||
provider: |
||||
dependency: "direct main" |
||||
description: |
||||
name: provider |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "6.0.2" |
||||
pub_semver: |
||||
dependency: transitive |
||||
description: |
||||
name: pub_semver |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.1" |
||||
pubspec_parse: |
||||
dependency: transitive |
||||
description: |
||||
name: pubspec_parse |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.2.0" |
||||
shared_preferences: |
||||
dependency: "direct main" |
||||
description: |
||||
name: shared_preferences |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.13" |
||||
shared_preferences_android: |
||||
dependency: transitive |
||||
description: |
||||
name: shared_preferences_android |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.11" |
||||
shared_preferences_ios: |
||||
dependency: transitive |
||||
description: |
||||
name: shared_preferences_ios |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.0" |
||||
shared_preferences_linux: |
||||
dependency: transitive |
||||
description: |
||||
name: shared_preferences_linux |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.0" |
||||
shared_preferences_macos: |
||||
dependency: transitive |
||||
description: |
||||
name: shared_preferences_macos |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.3" |
||||
shared_preferences_platform_interface: |
||||
dependency: transitive |
||||
description: |
||||
name: shared_preferences_platform_interface |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.0" |
||||
shared_preferences_web: |
||||
dependency: transitive |
||||
description: |
||||
name: shared_preferences_web |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.3" |
||||
shared_preferences_windows: |
||||
dependency: transitive |
||||
description: |
||||
name: shared_preferences_windows |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.0" |
||||
shelf: |
||||
dependency: transitive |
||||
description: |
||||
name: shelf |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.3.0" |
||||
shelf_web_socket: |
||||
dependency: transitive |
||||
description: |
||||
name: shelf_web_socket |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.1" |
||||
sky_engine: |
||||
dependency: transitive |
||||
description: flutter |
||||
source: sdk |
||||
version: "0.0.99" |
||||
source_gen: |
||||
dependency: transitive |
||||
description: |
||||
name: source_gen |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.2.2" |
||||
source_helper: |
||||
dependency: transitive |
||||
description: |
||||
name: source_helper |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.3.2" |
||||
source_span: |
||||
dependency: transitive |
||||
description: |
||||
name: source_span |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.8.2" |
||||
stack_trace: |
||||
dependency: transitive |
||||
description: |
||||
name: stack_trace |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.10.0" |
||||
stream_channel: |
||||
dependency: transitive |
||||
description: |
||||
name: stream_channel |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.0" |
||||
stream_transform: |
||||
dependency: transitive |
||||
description: |
||||
name: stream_transform |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.0.0" |
||||
string_scanner: |
||||
dependency: transitive |
||||
description: |
||||
name: string_scanner |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.1.0" |
||||
term_glyph: |
||||
dependency: transitive |
||||
description: |
||||
name: term_glyph |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.2.0" |
||||
test_api: |
||||
dependency: transitive |
||||
description: |
||||
name: test_api |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "0.4.9" |
||||
timing: |
||||
dependency: transitive |
||||
description: |
||||
name: timing |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.0" |
||||
typed_data: |
||||
dependency: transitive |
||||
description: |
||||
name: typed_data |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.3.0" |
||||
uuid: |
||||
dependency: "direct main" |
||||
description: |
||||
name: uuid |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "3.0.6" |
||||
vector_math: |
||||
dependency: transitive |
||||
description: |
||||
name: vector_math |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.1.2" |
||||
watcher: |
||||
dependency: transitive |
||||
description: |
||||
name: watcher |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "1.0.1" |
||||
web_socket_channel: |
||||
dependency: transitive |
||||
description: |
||||
name: web_socket_channel |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.2.0" |
||||
win32: |
||||
dependency: transitive |
||||
description: |
||||
name: win32 |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "2.5.2" |
||||
xdg_directories: |
||||
dependency: transitive |
||||
description: |
||||
name: xdg_directories |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "0.2.0+1" |
||||
yaml: |
||||
dependency: transitive |
||||
description: |
||||
name: yaml |
||||
url: "https://pub.dartlang.org" |
||||
source: hosted |
||||
version: "3.1.0" |
||||
sdks: |
||||
dart: ">=2.17.0-266.1.beta <3.0.0" |
||||
flutter: ">=2.8.1" |
@ -0,0 +1,82 @@
|
||||
name: logic_circuits_simulator |
||||
description: License project |
||||
|
||||
# The following line prevents the package from being accidentally published to |
||||
# pub.dev using `flutter pub publish`. This is preferred for private packages. |
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev |
||||
|
||||
# The following defines the version and build number for your application. |
||||
# A version number is three numbers separated by dots, like 1.2.43 |
||||
# followed by an optional build number separated by a +. |
||||
# Both the version and the builder number may be overridden in flutter |
||||
# build by specifying --build-name and --build-number, respectively. |
||||
# In Android, build-name is used as versionName while build-number used as versionCode. |
||||
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning |
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. |
||||
# Read more about iOS versioning at |
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html |
||||
version: 1.0.0+1 |
||||
|
||||
environment: |
||||
sdk: ">=2.17.0-266.1.beta <3.0.0" |
||||
|
||||
dependencies: |
||||
flutter: |
||||
sdk: flutter |
||||
cupertino_icons: ^1.0.2 |
||||
path_provider: ^2.0.9 |
||||
shared_preferences: ^2.0.13 |
||||
provider: ^6.0.2 |
||||
path: ^1.8.1 |
||||
json_annotation: ^4.5.0 |
||||
freezed: ^2.0.3 |
||||
freezed_annotation: ^2.0.3 |
||||
intl: ^0.17.0 |
||||
flutter_hooks: ^0.18.3 |
||||
uuid: ^3.0.6 |
||||
|
||||
dev_dependencies: |
||||
flutter_test: |
||||
sdk: flutter |
||||
|
||||
flutter_lints: ^2.0.0 |
||||
json_serializable: ^6.2.0 |
||||
build_runner: ^2.1.10 |
||||
|
||||
# For information on the generic Dart part of this file, see the |
||||
# following page: https://dart.dev/tools/pub/pubspec |
||||
|
||||
# The following section is specific to Flutter packages. |
||||
flutter: |
||||
uses-material-design: true |
||||
|
||||
# To add assets to your application, add an assets section, like this: |
||||
# assets: |
||||
# - images/a_dot_burr.jpeg |
||||
# - images/a_dot_ham.jpeg |
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see |
||||
# https://flutter.dev/assets-and-images/#resolution-aware |
||||
|
||||
# For details regarding adding assets from package dependencies, see |
||||
# https://flutter.dev/assets-and-images/#from-packages |
||||
|
||||
# To add custom fonts to your application, add a fonts section here, |
||||
# in this "flutter" section. Each entry in this list should have a |
||||
# "family" key with the font family name, and a "fonts" key with a |
||||
# list giving the asset and other descriptors for the font. For |
||||
# example: |
||||
# fonts: |
||||
# - family: Schyler |
||||
# fonts: |
||||
# - asset: fonts/Schyler-Regular.ttf |
||||
# - asset: fonts/Schyler-Italic.ttf |
||||
# style: italic |
||||
# - family: Trajan Pro |
||||
# fonts: |
||||
# - asset: fonts/TrajanPro.ttf |
||||
# - asset: fonts/TrajanPro_Bold.ttf |
||||
# weight: 700 |
||||
# |
||||
# For details regarding fonts from package dependencies, |
||||
# see https://flutter.dev/custom-fonts/#from-packages |
@ -0,0 +1,30 @@
|
||||
// This is a basic Flutter widget test. |
||||
// |
||||
// To perform an interaction with a widget in your test, use the WidgetTester |
||||
// utility in the flutter_test package. For example, you can send tap and scroll |
||||
// gestures. You can also use WidgetTester to find child widgets in the widget |
||||
// tree, read text, and verify that the values of widget properties are correct. |
||||
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_test/flutter_test.dart'; |
||||
|
||||
import 'package:logic_circuits_simulator/main.dart'; |
||||
|
||||
void main() { |
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async { |
||||
// Build our app and trigger a frame. |
||||
await tester.pumpWidget(const MyApp()); |
||||
|
||||
// Verify that our counter starts at 0. |
||||
expect(find.text('0'), findsOneWidget); |
||||
expect(find.text('1'), findsNothing); |
||||
|
||||
// Tap the '+' icon and trigger a frame. |
||||
await tester.tap(find.byIcon(Icons.add)); |
||||
await tester.pump(); |
||||
|
||||
// Verify that our counter has incremented. |
||||
expect(find.text('0'), findsNothing); |
||||
expect(find.text('1'), findsOneWidget); |
||||
}); |
||||
} |
After Width: | Height: | Size: 917 B |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 20 KiB |
@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<!-- |
||||
If you are serving your web app in a path other than the root, change the |
||||
href value below to reflect the base path you are serving from. |
||||
|
||||
The path provided below has to start and end with a slash "/" in order for |
||||
it to work correctly. |
||||
|
||||
For more details: |
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base |
||||
|
||||
This is a placeholder for base href that will be replaced by the value of |
||||
the `--base-href` argument provided to `flutter build`. |
||||
--> |
||||
<base href="$FLUTTER_BASE_HREF"> |
||||
|
||||
<meta charset="UTF-8"> |
||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible"> |
||||
<meta name="description" content="License project"> |
||||
|
||||
<!-- iOS meta tags & icons --> |
||||
<meta name="apple-mobile-web-app-capable" content="yes"> |
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black"> |
||||
<meta name="apple-mobile-web-app-title" content="logic_circuits_simulator"> |
||||
<link rel="apple-touch-icon" href="icons/Icon-192.png"> |
||||
|
||||
<!-- Favicon --> |
||||
<link rel="icon" type="image/png" href="favicon.png"/> |
||||
|
||||
<title>logic_circuits_simulator</title> |
||||
<link rel="manifest" href="manifest.json"> |
||||
|
||||
<script> |
||||
// The value below is injected by flutter build, do not touch. |
||||
var serviceWorkerVersion = null; |
||||
</script> |
||||
<!-- This script adds the flutter initialization JS code --> |
||||
<script src="flutter.js" defer></script> |
||||
</head> |
||||
<body> |
||||
<script> |
||||
window.addEventListener('load', function(ev) { |
||||
// Download main.dart.js |
||||
_flutter.loader.loadEntrypoint({ |
||||
serviceWorker: { |
||||
serviceWorkerVersion: serviceWorkerVersion, |
||||
} |
||||
}).then(function(engineInitializer) { |
||||
return engineInitializer.initializeEngine(); |
||||
}).then(function(appRunner) { |
||||
return appRunner.runApp(); |
||||
}); |
||||
}); |
||||
</script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,35 @@
|
||||
{ |
||||
"name": "logic_circuits_simulator", |
||||
"short_name": "logic_circuits_simulator", |
||||
"start_url": ".", |
||||
"display": "standalone", |
||||
"background_color": "#0175C2", |
||||
"theme_color": "#0175C2", |
||||
"description": "License project", |
||||
"orientation": "portrait-primary", |
||||
"prefer_related_applications": false, |
||||
"icons": [ |
||||
{ |
||||
"src": "icons/Icon-192.png", |
||||
"sizes": "192x192", |
||||
"type": "image/png" |
||||
}, |
||||
{ |
||||
"src": "icons/Icon-512.png", |
||||
"sizes": "512x512", |
||||
"type": "image/png" |
||||
}, |
||||
{ |
||||
"src": "icons/Icon-maskable-192.png", |
||||
"sizes": "192x192", |
||||
"type": "image/png", |
||||
"purpose": "maskable" |
||||
}, |
||||
{ |
||||
"src": "icons/Icon-maskable-512.png", |
||||
"sizes": "512x512", |
||||
"type": "image/png", |
||||
"purpose": "maskable" |
||||
} |
||||
] |
||||
} |