Browse Source

Initial commit

master
Kenneth Bruen 3 years ago
commit
c8b5168413
Signed by: kbruen
GPG Key ID: C1980A470C3EE5B1
  1. 11
      .args
  2. 47
      .gitignore
  3. 42
      .metadata
  4. 8
      .projectInfo
  5. 6
      .vscode/settings.json
  6. 16
      README.md
  7. 33
      analysis_options.yaml
  8. 13
      android/.gitignore
  9. 71
      android/app/build.gradle
  10. 8
      android/app/src/debug/AndroidManifest.xml
  11. 34
      android/app/src/main/AndroidManifest.xml
  12. 6
      android/app/src/main/kotlin/ro/dcdev/logic_circuits_simulator/MainActivity.kt
  13. 12
      android/app/src/main/res/drawable-v21/launch_background.xml
  14. 12
      android/app/src/main/res/drawable/launch_background.xml
  15. BIN
      android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  16. BIN
      android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  17. BIN
      android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  18. BIN
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  19. BIN
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  20. 18
      android/app/src/main/res/values-night/styles.xml
  21. 18
      android/app/src/main/res/values/styles.xml
  22. 8
      android/app/src/profile/AndroidManifest.xml
  23. 31
      android/build.gradle
  24. 3
      android/gradle.properties
  25. 6
      android/gradle/wrapper/gradle-wrapper.properties
  26. 11
      android/settings.gradle
  27. 34
      ios/.gitignore
  28. 26
      ios/Flutter/AppFrameworkInfo.plist
  29. 1
      ios/Flutter/Debug.xcconfig
  30. 1
      ios/Flutter/Release.xcconfig
  31. 481
      ios/Runner.xcodeproj/project.pbxproj
  32. 7
      ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  33. 8
      ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  34. 8
      ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  35. 87
      ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  36. 7
      ios/Runner.xcworkspace/contents.xcworkspacedata
  37. 8
      ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  38. 8
      ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  39. 13
      ios/Runner/AppDelegate.swift
  40. 122
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
  41. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  42. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  43. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  44. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  45. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  46. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  47. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  48. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  49. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  50. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  51. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  52. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  53. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  54. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  55. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  56. 23
      ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
  57. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
  58. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
  59. BIN
      ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
  60. 5
      ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
  61. 37
      ios/Runner/Base.lproj/LaunchScreen.storyboard
  62. 26
      ios/Runner/Base.lproj/Main.storyboard
  63. 49
      ios/Runner/Info.plist
  64. 1
      ios/Runner/Runner-Bridging-Header.h
  65. 100
      lib/dialogs/new_project.dart
  66. 106
      lib/main.dart
  67. 29
      lib/models/project.dart
  68. 425
      lib/models/project.freezed.dart
  69. 52
      lib/models/project.g.dart
  70. 24
      lib/models/projects.dart
  71. 327
      lib/models/projects.freezed.dart
  72. 33
      lib/models/projects.g.dart
  73. 185
      lib/pages/edit_component.dart
  74. 240
      lib/pages/project.dart
  75. 204
      lib/pages/projects.dart
  76. 17
      lib/pages/settings.dart
  77. 13
      lib/pages_arguments/edit_component.dart
  78. 170
      lib/pages_arguments/edit_component.freezed.dart
  79. 109
      lib/state/project.dart
  80. 80
      lib/state/projects.dart
  81. 7
      lib/utils/provider_hook.dart
  82. 1
      linux/.gitignore
  83. 138
      linux/CMakeLists.txt
  84. 88
      linux/flutter/CMakeLists.txt
  85. 11
      linux/flutter/generated_plugin_registrant.cc
  86. 15
      linux/flutter/generated_plugin_registrant.h
  87. 23
      linux/flutter/generated_plugins.cmake
  88. 6
      linux/main.cc
  89. 104
      linux/my_application.cc
  90. 18
      linux/my_application.h
  91. 670
      pubspec.lock
  92. 82
      pubspec.yaml
  93. 30
      test/widget_test.dart
  94. BIN
      web/favicon.png
  95. BIN
      web/icons/Icon-192.png
  96. BIN
      web/icons/Icon-512.png
  97. BIN
      web/icons/Icon-maskable-192.png
  98. BIN
      web/icons/Icon-maskable-512.png
  99. 58
      web/index.html
  100. 35
      web/manifest.json
  101. Some files were not shown because too many files have changed in this diff Show More

11
.args

@ -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

47
.gitignore vendored

@ -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

42
.metadata

@ -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'

8
.projectInfo

@ -0,0 +1,8 @@
>JDK Path
null
>Main Class
-
>Language Tag
--1
>Opened Editors on Main Tab Panel
-project-root$/lib/main.dart

6
.vscode/settings.json vendored

@ -0,0 +1,6 @@
{
"files.exclude": {
"**/*.freezed.dart": true,
"**/*.g.dart": true
}
}

16
README.md

@ -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.

33
analysis_options.yaml

@ -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

13
android/.gitignore vendored

@ -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

71
android/app/build.gradle

@ -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"
}

8
android/app/src/debug/AndroidManifest.xml

@ -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>

34
android/app/src/main/AndroidManifest.xml

@ -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>

6
android/app/src/main/kotlin/ro/dcdev/logic_circuits_simulator/MainActivity.kt

@ -0,0 +1,6 @@
package ro.dcdev.logic_circuits_simulator
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

12
android/app/src/main/res/drawable-v21/launch_background.xml

@ -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>

12
android/app/src/main/res/drawable/launch_background.xml

@ -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>

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

18
android/app/src/main/res/values-night/styles.xml

@ -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>

18
android/app/src/main/res/values/styles.xml

@ -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>

8
android/app/src/profile/AndroidManifest.xml

@ -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>

31
android/build.gradle

@ -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
}

3
android/gradle.properties

@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

6
android/gradle/wrapper/gradle-wrapper.properties vendored

@ -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

11
android/settings.gradle

@ -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"

34
ios/.gitignore vendored

@ -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

26
ios/Flutter/AppFrameworkInfo.plist

@ -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>

1
ios/Flutter/Debug.xcconfig

@ -0,0 +1 @@
#include "Generated.xcconfig"

1
ios/Flutter/Release.xcconfig

@ -0,0 +1 @@
#include "Generated.xcconfig"

481
ios/Runner.xcodeproj/project.pbxproj

@ -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 */;
}

7
ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata generated

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

8
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

8
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

@ -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>

87
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

@ -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>

7
ios/Runner.xcworkspace/contents.xcworkspacedata generated

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>

8
ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

8
ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

@ -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>

13
ios/Runner/AppDelegate.swift

@ -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)
}
}

122
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json

@ -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"
}
}

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

23
ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json vendored

@ -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"
}
}

BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

5
ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md vendored

@ -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.

37
ios/Runner/Base.lproj/LaunchScreen.storyboard

@ -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>

26
ios/Runner/Base.lproj/Main.storyboard

@ -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>

49
ios/Runner/Info.plist

@ -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>

1
ios/Runner/Runner-Bridging-Header.h

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

100
lib/dialogs/new_project.dart

@ -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(),
),
),
),
],
),
),
),
);
}
}

106
lib/main.dart

@ -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),
)
],
),
),
);
}
}

29
lib/models/project.dart

@ -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);
}

425
lib/models/project.freezed.dart

@ -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;
}

52
lib/models/project.g.dart

@ -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;
}

24
lib/models/projects.dart

@ -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);
}

327
lib/models/projects.freezed.dart

@ -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;
}

33
lib/models/projects.g.dart

@ -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,
};

185
lib/pages/edit_component.dart

@ -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(),
);
},
),
);
}
}

240
lib/pages/project.dart

@ -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');
}
},
),
),
],
),
),
);
}
}

204
lib/pages/projects.dart

@ -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');
}
},
),
),
],
),
),
);
}
}

17
lib/pages/settings.dart

@ -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,
),
);
}
}

13
lib/pages_arguments/edit_component.dart

@ -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;
}

170
lib/pages_arguments/edit_component.freezed.dart

@ -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;
}

109
lib/state/project.dart

@ -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);
}
}

80
lib/state/projects.dart

@ -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]
)
);
}
}

7
lib/utils/provider_hook.dart

@ -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);
}

1
linux/.gitignore vendored

@ -0,0 +1 @@
flutter/ephemeral

138
linux/CMakeLists.txt

@ -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()

88
linux/flutter/CMakeLists.txt

@ -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}
)

11
linux/flutter/generated_plugin_registrant.cc

@ -0,0 +1,11 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
void fl_register_plugins(FlPluginRegistry* registry) {
}

15
linux/flutter/generated_plugin_registrant.h

@ -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_

23
linux/flutter/generated_plugins.cmake

@ -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)

6
linux/main.cc

@ -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);
}

104
linux/my_application.cc

@ -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));
}

18
linux/my_application.h

@ -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_

670
pubspec.lock

@ -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"

82
pubspec.yaml

@ -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

30
test/widget_test.dart

@ -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);
});
}

BIN
web/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

BIN
web/icons/Icon-192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
web/icons/Icon-512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
web/icons/Icon-maskable-192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
web/icons/Icon-maskable-512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

58
web/index.html

@ -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>

35
web/manifest.json

@ -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"
}
]
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save