├── .gitattributes
├── .gitignore
├── .metadata
├── LICENSE
├── README.md
├── RELEASE.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── matrix
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── archive
├── localStorage_todoMVC
│ ├── common.cljd
│ ├── core.cljd
│ ├── footer.cljd
│ ├── input.cljd
│ ├── items.cljd
│ ├── persist.cljd
│ └── todo.cljd
└── x045_websocket.cljd
├── audio
├── drum-1.mp3
├── intro-1.mp3
├── notify-1.mp3
├── notify-2.mp3
└── scary.mp3
├── clean.sh
├── cljd.edn
├── deps.edn
├── doc
├── flutter-tts-makeover.key
├── flutter-tts-makeover.pdf
└── london clojurians October 2023 v2.pdf
├── examples
├── example
│ ├── demo
│ │ ├── ai
│ │ │ └── gemini
│ │ │ │ ├── advanced_text.cljd
│ │ │ │ ├── advanced_text_stream.cljd
│ │ │ │ ├── simple_chat.cljd
│ │ │ │ ├── simple_text.cljd
│ │ │ │ └── simple_text_and_image.cljd
│ │ ├── boiler
│ │ │ └── core.cljc
│ │ ├── fmx_inspector
│ │ │ ├── fmx_inspector.cljd
│ │ │ └── tree_view.cljd
│ │ ├── isolate
│ │ │ ├── common.cljd
│ │ │ ├── ixp
│ │ │ │ ├── cheats.cljd
│ │ │ │ ├── common.cljd
│ │ │ │ ├── health.cljd
│ │ │ │ ├── iso_control.cljd
│ │ │ │ ├── ixp.cljd
│ │ │ │ └── spawn_control.cljd
│ │ │ ├── x00_compute.cljd
│ │ │ ├── x00_spawn.cljd
│ │ │ ├── x01_iso_explorer.cljd
│ │ │ ├── x01_simple_bidirectional_link.cljd
│ │ │ ├── x02_poc_mx_iso.cljd
│ │ │ ├── x03_mx_isolate.cljd
│ │ │ ├── x042_iso_toggle.cljd
│ │ │ ├── x04_api_mx_iso.cljd
│ │ │ └── x070_mqtt5.cljd
│ │ ├── navigation
│ │ │ ├── component.cljd
│ │ │ ├── puzzle.cljd
│ │ │ ├── trainer.cljd
│ │ │ └── tree.cljd
│ │ ├── parrot
│ │ │ ├── component.cljd
│ │ │ ├── core.cljd
│ │ │ ├── fts.cljd
│ │ │ ├── poetry.cljd
│ │ │ └── stt
│ │ │ │ ├── common.cljd
│ │ │ │ ├── core.cljd
│ │ │ │ └── recorder.cljd
│ │ ├── todoMVC
│ │ │ ├── common.cljd
│ │ │ ├── core.cljd
│ │ │ ├── footer.cljd
│ │ │ ├── input.cljd
│ │ │ ├── items.cljd
│ │ │ ├── persist.cljd
│ │ │ └── todo.cljd
│ │ ├── todoMVX
│ │ │ ├── README.md
│ │ │ ├── common.cljd
│ │ │ ├── core.cljd
│ │ │ ├── footer.cljd
│ │ │ ├── input.cljd
│ │ │ ├── items.cljd
│ │ │ ├── persist.cljd
│ │ │ ├── state.cljd
│ │ │ ├── supa.cljd
│ │ │ ├── todo.cljd
│ │ │ └── todoMVX.sql
│ │ └── tts
│ │ │ ├── component.cljd
│ │ │ ├── core.cljd
│ │ │ ├── draft.cljd
│ │ │ ├── fts.cljd
│ │ │ └── poetry.cljd
│ ├── driver.cljc
│ ├── eg
│ │ ├── flutter_layout_tutorial.cljd
│ │ ├── flutter_tts.cljd
│ │ ├── x00_hello_world.cljd
│ │ ├── x01_counter.cljd
│ │ ├── x01_counter_desugared.cljd
│ │ ├── x020_reactive_stream.cljd
│ │ ├── x028_bottom_navbar.cljd
│ │ ├── x029_layout_builder.cljd
│ │ ├── x029a_layout_kid_builder.cljd
│ │ ├── x02_two_counters_ala_flux.cljd
│ │ ├── x02_two_counters_ala_matrix.cljd
│ │ ├── x030_codelab_namer.cljd
│ │ ├── x035_timer_poll.cljd
│ │ ├── x03_physics_sim.cljd
│ │ ├── x040_named_routes.cljd
│ │ ├── x046_websocket_lob.cljd
│ │ ├── x04_drawer.cljd
│ │ ├── x050_just_audio.cljd
│ │ ├── x055_isolates.cljd
│ │ ├── x05_fab.cljd
│ │ ├── x060_form_class.cljd
│ │ ├── x065_autocomplete_basic.cljd
│ │ ├── x066_autocomplete_object.cljd
│ │ ├── x06_tabs.cljd
│ │ ├── x070_speech_to_text.cljd
│ │ ├── x07_animated_container.cljd
│ │ ├── x08_navigation.cljd
│ │ ├── x09_form_change.cljd
│ │ ├── x09_form_input.cljd
│ │ ├── x10_datatable.cljd
│ │ ├── x11_grid_list.cljd
│ │ ├── x12_gesture_detector.cljd
│ │ ├── x13_snackbar.cljd
│ │ ├── x14_hero.cljd
│ │ ├── x15_fade_widget.cljd
│ │ ├── x25_flutter_tex.cljd
│ │ ├── x26_latex_sandbox.cljd
│ │ └── x27_popup_menu.cljd
│ └── non_fmx
│ │ ├── ctx_row.cljd
│ │ └── ifernandez_isolates.cljd
└── learn
│ └── counter
│ └── counter_fmx.cljd
├── fonts
├── Inter-Regular.ttf
├── RobotoMono-Light.ttf
└── RobotoMono-Thin.ttf
├── goopi.sh
├── image
├── 800px-Depth-first-tree.svg.png
├── Depth-First-Search.gif
├── HW d Sim.png
├── HW d all.png
├── HW d chrome.png
├── HW d macos.png
├── cat_on_snow.jpeg
├── counter-app.png
├── earth.png
├── einstein.jpeg
├── game-over.png
├── hello-world-app.jpg
├── jmccarthy.jpeg
├── john.jpeg
├── kenny-naut.png
├── kernighan.jpeg
├── lake-oeschinen.jpeg
├── scone.jpeg
├── todomvc-app.jpeg
├── trophy.jpeg
└── under-construction.jpeg
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
└── RunnerTests
│ └── RunnerTests.swift
├── lib
└── main.dart
├── macos
├── .gitignore
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── app_icon_1024.png
│ │ │ ├── app_icon_128.png
│ │ │ ├── app_icon_16.png
│ │ │ ├── app_icon_256.png
│ │ │ ├── app_icon_32.png
│ │ │ ├── app_icon_512.png
│ │ │ └── app_icon_64.png
│ ├── Base.lproj
│ │ └── MainMenu.xib
│ ├── Configs
│ │ ├── AppInfo.xcconfig
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── Warnings.xcconfig
│ ├── DebugProfile.entitlements
│ ├── Info.plist
│ ├── MainFlutterWindow.swift
│ └── Release.entitlements
└── RunnerTests
│ └── RunnerTests.swift
├── other
├── flutter-fab.dart
└── physics_sim_std.cljd
├── pom.xml
├── pubspec.yaml
├── src
└── tilton
│ ├── counter_app.cljc
│ ├── fmx
│ ├── api.cljd
│ ├── factory.cljd
│ ├── material.cljd
│ └── widgets.cljd
│ ├── main.cljd
│ ├── mx
│ ├── api.cljd
│ ├── base.cljd
│ ├── cell
│ │ ├── base.cljd
│ │ ├── core.cljd
│ │ ├── evaluate.cljd
│ │ ├── integrity.cljd
│ │ ├── observer.cljd
│ │ └── synapse.cljd
│ ├── foundation.cljd
│ ├── model
│ │ ├── base.cljd
│ │ ├── core.cljd
│ │ ├── navigate.cljd
│ │ └── peek.cljd
│ └── util.cljd
│ ├── test
│ ├── cell_core.cljd
│ ├── evaluate.cljd
│ ├── family_kids.cljd
│ ├── hello_cells.cljd
│ ├── integrity.cljd
│ ├── lazy_cells.cljd
│ ├── model_core.cljd
│ ├── observer.cljd
│ └── synapse.cljd
│ └── testing.cljd
├── sup.sh
├── sup_macos.sh
├── supmvx.sh
├── supweb.sh
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ ├── Icon-512.png
│ ├── Icon-maskable-192.png
│ └── Icon-maskable-512.png
├── index.html
└── manifest.json
└── windows
├── .gitignore
├── CMakeLists.txt
├── flutter
├── CMakeLists.txt
├── generated_plugin_registrant.cc
├── generated_plugin_registrant.h
└── generated_plugins.cmake
└── runner
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── resources
└── app_icon.ico
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.cljd linguist-language=Clojure
2 | # Syntax highlighting for ClojureDart files
3 | *.cljd linguist-language=Clojure
4 |
5 | # Syntax highlighting for ClojureDart files
6 | *.cljd linguist-language=Clojure
7 |
8 | # Syntax highlighting for ClojureDart files
9 | *.cljd linguist-language=Clojure
10 |
11 | # Syntax highlighting for ClojureDart files
12 | *.cljd linguist-language=Clojure
13 |
14 | # Syntax highlighting for ClojureDart files
15 | *.cljd linguist-language=Clojure
16 |
17 | # Syntax highlighting for ClojureDart files
18 | *.cljd linguist-language=Clojure
19 |
20 | # Syntax highlighting for ClojureDart files
21 | *.cljd linguist-language=Clojure
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | .nrepl-port
12 |
13 | demo-video
14 | linux
15 | android
16 | other
17 | out
18 |
19 | # IntelliJ related
20 | *.iml
21 | *.ipr
22 | *.iws
23 | .idea/
24 |
25 | # The .vscode folder contains launch configuration and tasks you configure in
26 | # VS Code which you may wish to be included in version control, so this line
27 | # is commented out by default.
28 | #.vscode/
29 |
30 | # Flutter/Dart/Pub related
31 | **/doc/api/
32 | **/ios/Flutter/.last_build_id
33 | .flutter-plugins
34 | .flutter-plugins-dependencies
35 | .packages
36 | .pub-cache/
37 | .pub/
38 | /build/
39 | /lib/cljd-out/
40 | /ios/build/
41 | /test/
42 |
43 | .cpcache
44 | .lsp/.cache
45 | .clj-kondo/*
46 | .clojuredart
47 | .dart_tool
48 | pubspec.lock
49 |
50 |
51 | # Web related
52 |
53 | # Symbolication related
54 | app.*.symbols
55 |
56 | # Obfuscation related
57 | app.*.map.json
58 |
59 | # Android Studio will place build artifacts here
60 | /android/app/debug
61 | /android/app/profile
62 | /android/app/release
63 |
64 | # ClojureDart
65 | .cpcache/
66 | .clojuredart/
67 | lib/cljd-out/
68 | test/cljd-out/
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled.
5 |
6 | version:
7 | revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
8 | channel: stable
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
17 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
18 | - platform: android
19 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
20 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
21 | - platform: ios
22 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
23 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
24 | - platform: linux
25 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
26 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
27 | - platform: macos
28 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
29 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
30 | - platform: web
31 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
32 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
33 | - platform: windows
34 | create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
35 | base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Kenneth Tilton
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion flutter.compileSdkVersion
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlinOptions {
37 | jvmTarget = '1.8'
38 | }
39 |
40 | sourceSets {
41 | main.java.srcDirs += 'src/main/kotlin'
42 | }
43 |
44 | defaultConfig {
45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
46 | applicationId "com.example.matrix"
47 | minSdkVersion flutter.minSdkVersion
48 | targetSdkVersion flutter.targetSdkVersion
49 | versionCode flutterVersionCode.toInteger()
50 | versionName flutterVersionName
51 | }
52 |
53 | buildTypes {
54 | release {
55 | // TODO: Add your own signing config for the release build.
56 | // Signing with the debug keys for now, so `flutter run --release` works.
57 | signingConfig signingConfigs.debug
58 | }
59 | }
60 | }
61 |
62 | flutter {
63 | source '../..'
64 | }
65 |
66 | dependencies {
67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
68 | }
69 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/matrix/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.matrix
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.6.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/archive/localStorage_todoMVC/common.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.localStorage-todoMVC.common
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:shared_preferences/shared_preferences.dart" :as prefs]))
5 |
6 | (defn title-red []
7 | (.fromRGBO m/Color 184 63 69 0.5))
8 |
9 | (defmacro my-todo-list []
10 | `(tilton.mx.model.base/mget
11 | (tilton.mx.model.core/fasc :app)
12 | :todo-list))
13 |
--------------------------------------------------------------------------------
/archive/localStorage_todoMVC/input.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.localStorage-todoMVC.input
2 | (:require
3 | ["package:flutter/widgets.dart" :as w]
4 | ["package:flutter/material.dart" :as m]
5 | ["package:flutter/painting.dart" :as p]
6 | [clojure.string :as str]
7 | [tilton.mx.api :refer [cF cI cFonce mget mswap! mset!]]
8 | [tilton.fmx.api :refer [dart-cb my-app] :as fx]
9 | [example.demo.localStorage-todoMVC.common :refer [ my-todo-list ] :as cmm]
10 | [example.demo.localStorage-todoMVC.todo :refer [td-completed] :as todo]))
11 |
12 | (defn todo-input-onSubmitted-formula []
13 | (cF (dart-cb [value]
14 | ;; blank or not we need to restore focus to the input per the spec
15 | (.requestFocus ^m/FocusNode (mget me :focusNode))
16 | ;; spec says to trim, and to silently ignore blank entry
17 | (let [trimmed (str/trim value)]
18 | (when-not (str/blank? trimmed)
19 | ;; --- we have a non-blank entry, so we save, clear entry, and store
20 | (mset! me :value trimmed) ;; let text proxy know its cleaned value
21 | (.clear ^m/TextEditingController
22 | (mget me :controller))
23 | (let [td-lst (my-todo-list)]
24 | (mswap! td-lst :kids conj
25 | (todo/make-ToDo td-lst trimmed false))))))))
26 |
27 | (defn todo-input []
28 | (fx/material {:elevation 20.0
29 | :color m/Colors.white
30 | :shadowColor m/Colors.black}
31 | (fx/text-field {:autofocus true
32 | :focusNode (m/FocusNode)
33 | :decoration (m/InputDecoration
34 | .hintText "What needs doing?"
35 | .border m.InputBorder/none
36 | .contentPadding (m/EdgeInsets.all 9.0))
37 | :onSubmitted (todo-input-onSubmitted-formula)
38 | :controller (cFonce (fx/text-field-controller-basic me))}
39 | {:name :todo-input
40 | ;; todo get prefill working. standard controller not picking up value
41 | :value (cI "test")})))
42 |
43 | (defn todo-toggle-all []
44 | (fx/visibility
45 | {:visible (cF (boolean
46 | (seq (todo/app-todos (my-app)))))
47 | ;; todo: composability with fixed arity reusables as case may be.
48 | :maintainSize true
49 | :maintainSemantics false
50 | ;; todo why do not other visis specify these ^^^ vvvv?
51 | :maintainInteractivity false
52 | :maintainAnimation true
53 | :maintainState true}
54 | (fx/icon-button
55 | {:onPressed (dart-cb []
56 | (let [todos (todo/app-todos (my-app))
57 | all-done? (every? td-completed todos)]
58 | (doseq [td todos]
59 | ;; todo do all these in one change pulse
60 | (mset! td :completed (if all-done? false true)))))
61 | :icon (m/Icon m.Icons/expand_more .color m/Colors.blueGrey)})))
62 |
63 | (defn todo-controls []
64 | (fx/row
65 | (fx/expanded {:flex 1}
66 | ;; handy widget to mark all to-dos at once
67 | (todo-toggle-all))
68 | ; --- the to-do input field ----
69 | (fx/expanded {:flex 9}
70 | (fx/padding
71 | {:padding (m/EdgeInsets.all 16.0)}
72 | (todo-input)))))
--------------------------------------------------------------------------------
/archive/localStorage_todoMVC/persist.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.localStorage-todoMVC.persist
2 | (:require
3 | ["package:shared_preferences/shared_preferences.dart" :as prefs]
4 | ["dart:convert" :as convert]
5 | ["package:uuid/uuid.dart" :as uu]
6 | [tilton.mx.base :refer [dprn dp dpx]]
7 | [tilton.mx.util :as util]
8 | [clojure.walk :as walk]))
9 |
10 | (def +DB+ (atom nil)) ;; n.b. just a cache, NOT reactive
11 | (defn ^prefs/SharedPreferences? DB [] (deref +DB+))
12 | (defn ^prefs/SharedPreferences? DB! [db] (reset! +DB+ db))
13 |
14 | (def +uuid+ (atom nil))
15 | (defn ^uu/Uuid UUID []
16 | (or (deref +uuid+)
17 | (uu/Uuid)))
18 |
19 | (defn td-store
20 | "Write a CLJD ToDo map to persistent storage.
21 | Map must contain :stg-id, a string identifier.
22 | Returns the stg-id."
23 | [td-map]
24 | (let [stg-id (:stg-id td-map)]
25 | (assert stg-id "td-rewrite map must include stg-id")
26 | (.setString (DB) stg-id
27 | (convert/jsonEncode
28 | (walk/stringify-keys
29 | (select-keys td-map
30 | [:stg-id :created-at :title :completed]))))
31 | stg-id))
32 |
33 | (defn td-initialize
34 | "Create a SharedPrefs to-do from a CLJD map alone.
35 | Returns the unique storage key generated for the data."
36 | [collection-name td-map]
37 | (when-let [stg-id (:stg-id td-map)]
38 | (throw (Exception. (str "td-initialize> sees :stg-id " stg-id ", suggesting td already written"))))
39 |
40 | (let [new-stg-id (str collection-name "/" (.v4 (UUID)))]
41 | (td-store
42 | (assoc td-map :stg-id new-stg-id))
43 | new-stg-id))
44 |
45 | (defn td-rewrite
46 | "Update a stored to-do given only a CLJD map of its properties.
47 | Map must contain non-nil :stg-id."
48 | [td-map]
49 | (assert (:stg-id td-map)
50 | "td-rewrite> map must include stg-id")
51 | (td-store td-map)
52 | (:stg-id td-map))
53 |
54 | (defn td-delete
55 | "Deletes storage associated with stg-id."
56 | [stg-id]
57 | (assert stg-id "td-delete> stg-id argument is nil. s/b string ID.")
58 | (.remove (DB) stg-id)
59 | stg-id)
60 |
61 | ;;; --- collection-level utilities -------------
62 |
63 | (defn collection-docs [collection-name]
64 | (let [all-td-keys (collection-keys collection-name)]
65 | (mapv (fn [td-key]
66 | (util/dart-map->cljd-map
67 | (convert/jsonDecode (.getString (DB) td-key))))
68 | all-td-keys)))
69 |
70 | (defn collection-keys [collection-name]
71 | (into #{}
72 | (filter #(= collection-name
73 | (subs % 0 (count collection-name)))
74 | (.getKeys (DB)))))
75 |
76 | (defn collection-delete-all [collection-name]
77 | (doseq [k (collection-keys collection-name)]
78 | (td-delete k)))
--------------------------------------------------------------------------------
/audio/drum-1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/audio/drum-1.mp3
--------------------------------------------------------------------------------
/audio/intro-1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/audio/intro-1.mp3
--------------------------------------------------------------------------------
/audio/notify-1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/audio/notify-1.mp3
--------------------------------------------------------------------------------
/audio/notify-2.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/audio/notify-2.mp3
--------------------------------------------------------------------------------
/audio/scary.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/audio/scary.mp3
--------------------------------------------------------------------------------
/clean.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # shut down any builder
4 |
5 | # on sim:
6 | # - erase all content
7 | # - restart
8 |
9 | # in repo:
10 | touch pubspec.yaml
11 | rm -rf .clojuredart
12 | rm -rf lib/cljd-out
13 | flutter clean
14 |
15 | # now: clj -M -m cljd.build flutter
--------------------------------------------------------------------------------
/cljd.edn:
--------------------------------------------------------------------------------
1 | {:main tilton.main, :bin "flutter"}
--------------------------------------------------------------------------------
/deps.edn:
--------------------------------------------------------------------------------
1 | {:paths ["src" "examples" ]
2 | :cljd/opts {:kind :flutter
3 | :main tilton.main}
4 | :aliases {:cljd {:main-opts ["-m" "cljd.build"]}}
5 | :deps {org.clojure/data.json {:mvn/version "2.4.0"}
6 | tensegritics/clojuredart
7 | {:git/url "https://github.com/Tensegritics/ClojureDart.git"
8 | :sha "6127d8ef23156f2be5b10e97a0932868d175e585" #_"0e1ef256cf3a0ee9b71db6d4af3d8be581b95195" #_"98463fae4e5fe50566b38e688cfed78071ea91a1"}}}
9 |
--------------------------------------------------------------------------------
/doc/flutter-tts-makeover.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/doc/flutter-tts-makeover.key
--------------------------------------------------------------------------------
/doc/flutter-tts-makeover.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/doc/flutter-tts-makeover.pdf
--------------------------------------------------------------------------------
/doc/london clojurians October 2023 v2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/doc/london clojurians October 2023 v2.pdf
--------------------------------------------------------------------------------
/examples/example/demo/boiler/core.cljc:
--------------------------------------------------------------------------------
1 | (ns example.demo.boiler.core
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | [tilton.mx.cell.base :as cty]
6 | [tilton.mx.model.core :refer [make]]
7 | [tilton.mx.api :refer [dp minfo cF cI cFn cFonce mmx-md mget mset! mswap! fm* fmu fasc mav] :as mx]
8 | [tilton.fmx.api :as fx
9 | :refer [dart-cb within-ctx
10 | material-app scaffold app-bar floating-action-button
11 | center column text sized-box]]))
12 |
13 | (defn make-app []
14 | (cty/cells-reset)
15 | (let [b (make :on? (tilton.mx.cell.core/make-cell
16 | :watch (fn [slot me new prior c]
17 | (dp :CHG! slot :now new :was prior))
18 | :value true
19 | :input? true)
20 | :burner (tilton.mx.cell.core/make-c-formula
21 | :watch (fn [slot me new prior c]
22 | (dp :CHG! slot :now new :was prior))
23 | :rule (tilton.mx.cell.core/c-fn
24 | (if (mget me :on?)
25 | :blasting :off)))
26 | #_ (cF (if (mget me :on?)
27 | :blasting :off)))]
28 | ;(dp :startxx :on (mget b :on?) :burner-on (mget b :burner))
29 | ;;(mset! b :burner :off) ;; todo fails on wrong error, but only if :on? is not cI
30 | (mset! b :on? false)
31 | #_ (dp :post-on-false :on (mget b :on?) :burner-on (mget b :burner)))
32 |
33 | (let [title "Boiler Demo X"]
34 | (material-app
35 | {:title title
36 | :theme (m/ThemeData .useMaterial3 true
37 | .colorScheme (m/ColorScheme.fromSeed
38 | .seedColor m/Colors.deepPurple))}
39 | (scaffold
40 | {:appBar (app-bar
41 | {:title (m/Text title)
42 | :backgroundColor (cF (.-inversePrimary
43 | (.-colorScheme ^m/ThemeData (mav :theme))))})
44 |
45 | ;---------- how abaout fma-get, -set!, -swap! ????
46 |
47 | :floatingActionButton
48 | (floating-action-button
49 | {:onPressed (dart-cb []
50 | (mswap! (fm* :counter) :value inc))
51 | :tooltip "Increment"}
52 | (m/Icon m/Icons.add .color m/Colors.black))}
53 | (center
54 | (column {:mainAxisAlignment m/MainAxisAlignment.center}
55 | (text {:style (p/TextStyle .color m/Colors.black
56 | .fontSize 20.0)}
57 | "The button push count now:")
58 | (sized-box
59 | {:height 28.0})
60 | (text
61 | {:style (cF (fx/within-ctx [me ctx]
62 | (-> (m/Theme.of ctx) .-textTheme .-displayMedium))
63 | #_(.-displayLarge (.-textTheme ^m/ThemeData (mav :theme))))}
64 | {:name :counter
65 | :value (cI 0)}
66 | (str (mget me :value)))))))))
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/examples/example/demo/fmx_inspector/fmx_inspector.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.fmx-inspector.fmx-inspector
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | ["package:flutter/widgets.dart" :as w]
6 | ["package:english_words/english_words.dart" :as en]
7 | [tilton.mx.api :refer [minfo dpx dp cF cFn cI mget mset! mupdate! mav fasc fmu muv] :as mx]
8 | [tilton.mx.model.peek :refer [mname]]
9 | [tilton.fmx.api :refer [center column text sized-box dart-cb] :as fx]
10 | [example.demo.fmx-inspector.tree-view :as tv]
11 | [learn.counter.counter-fmx :as ctr]))
12 |
13 |
14 | ;;; --- utils ---------------------------------------------
15 |
16 | (defmacro even-row [& parts]
17 | `(row {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly}
18 | ~@parts))
19 |
20 | (defmacro app-section [& parts]
21 | `(column
22 | (m/Divider .thickness 0.5 .color m/Colors.grey)
23 | ~@parts))
24 |
25 | (defn mk-condensed? []
26 | ; (fx/sized-box {:width 300}
27 | (fx/checkbox-list-tile
28 | {:controlAffinity m/ListTileControlAffinity.leading
29 | :title (m/Text "condensed")
30 | :value (cF (mav :condensed?))
31 | :onChanged (cF (dart-cb [value]
32 | (mset! (fasc :inspector) :condensed? value)))}
33 | {:name :condensed?}))
34 |
35 | ;;; --- inspector ----------------------------------------
36 |
37 | (defn inspector-page [target excluding]
38 | (column {}
39 | {:name :inspector
40 | :target (cFn (fmu target))
41 | :condensed? (cI false)
42 | :selected-cell (cI #{})}
43 | (app-section
44 | (mk-condensed?))
45 | (app-section
46 | (fx/single-child-scroll-view
47 | {:scrollDirection m/Axis.horizontal}
48 | (fx/container
49 | {:constraints (m/BoxConstraints .minHeight 24)
50 | :margin (m/EdgeInsets.all 3)
51 | :decoration (cF (fx/box-decoration
52 | {:border (cF (.all m/Border .color m/Colors.blue .width 0.5))
53 | :color m/Colors.grey.shade50}))}
54 | (let [tgt (mav :target)]
55 | (dpx :top-tgt tgt)
56 | (tv/md-tree-view tgt)))))))
57 |
58 | ;;; --- make-app ---------------------------------------------------------------
59 |
60 | (defn make-app
61 | []
62 | (let [title "f/mx Inspector"]
63 | (fx/material-app {:title title
64 | :theme (m/ThemeData .fontFamily "RobotoMon")}
65 | (fx/default-tab-controller
66 | {:length 2 :initialIndex 0}
67 | (fx/scaffold
68 | {:appBar (fx/app-bar
69 | {:bottom (m/TabBar .tabs [(m/Tab .icon (m/Icon m/Icons.home .size 48))
70 | (m/Tab .icon (m/Icon m/Icons.public .size 48))])})}
71 | (fx/tab-bar-view
72 | (center {}
73 | {:name :blackjack}
74 | (ctr/home-page .title "Blackjack-ish"))
75 | (center {}
76 | {:name :inspector-socket}
77 | (inspector-page :blackjack nil))))))))
--------------------------------------------------------------------------------
/examples/example/demo/isolate/ixp/cheats.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.isolate.ixp.cheats)
2 |
3 | (comment
4 |
5 |
6 | (doto (.-instance m/WidgetsBinding)
7 | (.addPostFrameCallback
8 | (fn [^Duration d])))
9 |
10 | (defmacro post-frame [[duration-var] & body]
11 | `(doto (.-instance m/WidgetsBinding)
12 | (.addPostFrameCallback
13 | (fn [^Duration ~duration-var]
14 | ~@body))))
15 |
16 | (.-millisecondsSinceEpoch (.now DateTime)))
--------------------------------------------------------------------------------
/examples/example/demo/isolate/ixp/common.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.isolate.ixp.common
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | ["package:flutter/widgets.dart" :as w]
6 | [tilton.mx.api :as mx
7 | :refer [dp dpx cI cF cF+ cF+n cFn cFonce mget mget? mset! mswap! minfo fasc fasc-inc
8 | fmu muv fm* mav mx-bound? wmx-iso with-cc millis-now or-mx-bound]]))
9 |
10 | (defmacro result-clear []
11 | ; todo move to common
12 | `(tilton.mx.api/mset! (tilton.mx.api/fasc :app) :worker-msg
13 | {:msg-type :clear}))
--------------------------------------------------------------------------------
/examples/example/demo/isolate/ixp/health.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.isolate.ixp.health
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | ["package:flutter/widgets.dart" :as w]
6 | ["dart:io" :as io]
7 | ["dart:async" :as async]
8 | ["dart:convert" :as convert]
9 | [tilton.mx.api :as mx
10 | :refer [dp dpx cI cF cF+ cF+n cFn cFonce mget mget? mset! wmx-iso millis-now or-mx-bound]]
11 | [tilton.fmx.api :as fx
12 | :refer [scaffold app-bar text center column hero material-app
13 | container row expanded icon padding opacity ignore-pointer
14 | checkbox-list-tile icon-button fx-render dart-cb]]
15 | [example.demo.isolate.common :as cmn
16 | :refer [iso-ping]]
17 | ["dart:isolate" :as di
18 | :refer [Isolate SendPort Capability ReceivePort]]))
19 |
20 | (defonce HCINTERVAL 200)
21 |
22 | (defn mk-health-monitor [app iso to-iso]
23 | (mx/make
24 | ;; health
25 | :name :health-monitor
26 | :health-clock (cF+ [:watch (fn [_ _ _ prior _]
27 | (when (dart/is? prior async/Timer)
28 | (.cancel ^async/Timer prior)))
29 | :on-quiesce (fn [c] (when-let [tmr ^async/Timer (mx/c-value c)]
30 | (dp :ONQ-health-cancel!!!!!!!!!!!!!!!)
31 | (.cancel tmr)))]
32 | (async/Timer.periodic (Duration .milliseconds HCINTERVAL)
33 | (fn [^async/Timer tmr]
34 | (wmx-iso
35 | (mset! me :health-check
36 | {:msg-type "health-check"
37 | :epoch (millis-now)})))))
38 | :health-ack (cF (let [{:keys [msg-type response] :as msg} (mget app :worker-msg)]
39 | (cond
40 | (or (nil? msg)
41 | (not= :health-check-ack msg-type))
42 | (or-mx-bound _cache nil)
43 | :else response)))
44 |
45 | :health-check (cI nil :watch (fn [_ me check _ _]
46 | (when check
47 | (iso-ping iso to-iso
48 | Isolate.beforeNextEvent
49 | check))))
50 |
51 | :health (cF (if-let [chk (mget me :health-check)]
52 | (let [ack (mget me :health-ack)
53 | delta (cond
54 | (nil? ack) (- (millis-now) (:epoch chk))
55 | (< (:epoch ack) (:epoch chk)) (- (:epoch chk) (:epoch ack))
56 | :else (- (:epoch ack) (:epoch chk)))]
57 | (cond
58 | (>= delta (* 5 HCINTERVAL)) :dead
59 | (>= delta (* 1.5 HCINTERVAL)) :slow
60 | :else :healthy))
61 | :unchecked))))
--------------------------------------------------------------------------------
/examples/example/demo/isolate/ixp/iso_control.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.isolate.ixp.iso-control
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | ["package:flutter/widgets.dart" :as w]
6 | ["package:flutter/foundation.dart" :as fnd]
7 | ["dart:convert" :as convert]
8 | ["dart:math" :as math]
9 | [clojure.string :as str]
10 | [clojure.walk :as walk]
11 | [tilton.mx.api :as mx
12 | :refer [dp dpx cI cF cF+ mget mget? mset! mswap! minfo fasc
13 | mav with-cc millis-now or-mx-bound]]
14 | [tilton.fmx.api :as fx
15 | :refer [scaffold app-bar text center column hero material-app
16 | container row expanded icon padding opacity ignore-pointer
17 | checkbox-list-tile icon-button fx-render dart-cb]]
18 |
19 | ["dart:isolate" :as di
20 | :refer [Isolate SendPort ReceivePort]]
21 | [example.demo.isolate.common
22 | :refer [clock-face slow-is-prime? just-slow-is-prime?
23 | dbgiso iso-name say-delay m99 iso-ping]]
24 | [example.demo.isolate.ixp.common :refer [result-clear]]))
25 |
26 | ;;; --- job starters -----------
27 |
28 | (defn decide-in-main [n]
29 | (fx/elevated-button
30 | {:onPressed (cF (dart-cb []
31 | (result-clear)
32 | (doto (.-instance m/WidgetsBinding)
33 | (.addPostFrameCallback
34 | (fn [^Duration d]
35 | (mset! (fasc :app) :worker-msg
36 | {:msg-type :prime-decision
37 | :method "Main.iso"
38 | :n n
39 | :value (just-slow-is-prime? n)}))))))}
40 | (m/Text (str "Main " (m99 n)))))
41 |
42 | (defn decide-in-compute [n]
43 | (fx/elevated-button
44 | {:onPressed (cF (dart-cb []
45 | (result-clear)
46 | (mset! me :compute? true)))}
47 | {:compute? (cI false :ephemeral? true)
48 | :result (cF+ [:async? true
49 | :watch (fn [_ me new _ _]
50 | (when (not (nil? new))
51 | (with-cc :worker-res
52 | (mset! (fasc :app) :worker-msg
53 | {:msg-type :prime-decision
54 | :method "fnf/compute"
55 | :n n
56 | :value new}))))]
57 | (when (mget me :compute?)
58 | (fnd/compute just-slow-is-prime? n)))}
59 | (m/Text (str "Compute " (m99 n)))))
60 |
61 | (defn decide-in-run [n]
62 | (fx/elevated-button
63 | {:onPressed (dart-cb []
64 | (result-clear)
65 | (mset! (fasc :app) :run-job
66 | {:msg-type :decide-prime
67 | :n n
68 | :id (millis-now)
69 | :method "Iso.run"}))}
70 | (m/Text (str "Iso.run " (m99 n)))))
71 |
72 | ;;; --- worker result -----------------------------------------------
73 |
74 | (defn worker-msg-display []
75 | (text {:style (p/TextStyle .fontSize 16)}
76 | (let [{:keys [method msg-type n value] :as result} (mav :worker-msg)]
77 | (dpx :result msg-type n value method)
78 | (case msg-type
79 | :prime-decision (str (or method "Anon") " says " (or n "NIL") " is " (when-not value "NOT ") "prime.")
80 | :ping-ack (:response result)
81 | :alert (:msg result)
82 | :clear "..."
83 | (or-mx-bound _cache "")))))
84 |
85 |
--------------------------------------------------------------------------------
/examples/example/demo/isolate/x00_compute.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.isolate.x00-compute
2 | (:require
3 | ["package:flutter/gestures.dart" :as g]
4 | ["package:flutter/material.dart" :as m
5 | :refer [Canvas Size]]
6 | ["package:flutter/painting.dart" :as p]
7 | ["package:vector_math/vector_math_64.dart" :as vm]
8 | ["dart:math" :as math
9 | :refer [pi cos sin]]
10 | ["dart:async" :as async
11 | :refer [Completer StreamSubscription]]
12 | ["dart:isolate" :as di
13 | :refer [Isolate SendPort ReceivePort]]
14 | ["package:flutter/foundation.dart" :as fnd]
15 |
16 | [tilton.mx.cell.base :as cb]
17 | [tilton.mx.api :as mx
18 | :refer [dp dpx cI cF cF+ cF+n cFn cFonce mget mget? mset! mswap! minfo fasc fasc-inc
19 | navig fmu muv fm* mav mx-bound? wmx-iso with-cc]]
20 | [tilton.fmx.api :as fx]
21 | [example.demo.isolate.common :as cmn
22 | :refer [clock-face slow-is-prime? dbgiso]]))
23 |
24 | (defn use-compute? [starting]
25 | (fx/sized-box {:width 300}
26 | (fx/checkbox-list-tile
27 | {:controlAffinity m/ListTileControlAffinity.leading
28 | :title (m/Text "Use Foundation/compute?"
29 | .style (p/TextStyle
30 | .fontSize 24))
31 | :value (cI starting)
32 | :onChanged (cF #(wmx-iso
33 | (mset! me :value %)
34 | (mset! (fmu :primer) :of 9000039)))}
35 | {:name :use-compute?})))
36 |
37 | (declare prime-decision)
38 |
39 | (defn make-app []
40 | (let [title "Smooth Clock"]
41 | (fx/material-app
42 | {:title title}
43 | (fx/scaffold
44 | {:appBar (fx/app-bar {:title (fx/text title)})
45 | :floatingActionButton
46 | (fx/floating-action-button
47 | {:onPressed (fx/dart-cb []
48 | (wmx-iso
49 | (mswap! (fmu :primer) :of + 2)))}
50 | (m/Icon m/Icons.play_arrow
51 | .color m/Colors.black))}
52 | (fx/column
53 | {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly}
54 | (clock-face)
55 | (use-compute? false)
56 | (fx/row {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly}
57 | (fx/text {:style (p/TextStyle .fontSize 24)}
58 | {:name :primer
59 | :of (cI 9000039)
60 | :prime? (cF+ [:async? true]
61 | (let [n (mget me :of)
62 | use? (mx/muv :use-compute?)]
63 | (if use?
64 | (fnd/compute slow-is-prime? n)
65 | (future (slow-is-prime? n)))))}
66 | "" #_(str "Is " (mget me :of) " prime? "))
67 | ; ... results:
68 | (prime-decision))
69 | (fx/text {:style (p/TextStyle .fontSize 16)}
70 | "Tap for next in 9000041,.49,.59,.67,.."))))))
71 |
72 | (defn prime-decision []
73 | (fx/sized-box {:height 32}
74 | (fx/text
75 | {:style (cF (let [{:keys [prime?]} (mget (fmu :primer) :prime?)]
76 | (fx/text-style
77 | {:fontSize 24
78 | :fontWeight m/FontWeight.w400
79 | :color (if prime? m/Colors.green m/Colors.red)})))}
80 | {:name :prime-dec-text}
81 | (let [{:keys [of prime?]} (mget (fmu :primer) :prime?)]
82 | (dpx :decision-sees of :prime? prime?)
83 | (str "Is " of " prime? "
84 | (cond
85 | (nil? prime?) "..."
86 | (true? prime?) "Yep!!"
87 | (false? prime?) "Nope"
88 | :else "#@!%"))))))
89 |
--------------------------------------------------------------------------------
/examples/example/demo/isolate/x00_spawn.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.isolate.x00-spawn
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | ["package:flutter/widgets.dart" :as w]
6 | [clojure.string :as str]
7 | [tilton.mx.api :as mx
8 | :refer [dp dpx cI cF cF+ cF+n cFn cFonce mget mget? mset! mswap! minfo fasc fasc-inc
9 | fmu muv fm* mav mx-bound? wmx-iso]]
10 | [tilton.fmx.api :as fx
11 | :refer [scaffold app-bar text center column hero material-app
12 | container row expanded icon padding opacity ignore-pointer
13 | checkbox-list-tile icon-button fx-render dart-cb]]
14 | [example.demo.isolate.common :as cmn
15 | :refer [clock-face slow-is-prime? dbgiso say-delay]]
16 | ["dart:isolate" :as di
17 | :refer [Isolate SendPort ReceivePort]]))
18 |
19 | ;;; Inspired by Plague Fox, Example 1: https://plugfox.dev/mastering-isolates/
20 | ;;;
21 | ;;; we do nothing but spawn an isolate, watch it run, and watch it exit
22 | ;;;
23 | ;;; but play around with commenting/uncommenting below the delays and kills, etc, to get
24 | ;;; a feel for async and isolates.
25 |
26 | (defn factorial-worker [n]
27 | (dbgiso :worker-entry)
28 | (reduce (fn [a b]
29 | (let [f (* a b)]
30 | (dp :factorial-of b :is f)
31 | f))
32 | (range 1 (inc n)))
33 | ; (await (say-delay 2 :worker-pre-return))
34 | ; (await (Future.delayed (Duration .seconds 2)))
35 |
36 | ; if we do not trust dart:io to kill an iso on return...
37 | (do
38 | (dbgiso :worker-pre-exit)
39 | (Isolate.exit)
40 | (dp :YOU_SHOULD_NOT_SEE_THIS_WE_EXITED!!!!!!!!!!!!))
41 | )
42 |
43 | (defn make-app []
44 | (fx/material-app {}
45 | {:iso (cF+ [:async? true
46 | :watch (fn [_ me new-iso _ _]
47 | (dbgiso :watch-sees-new-iso new-iso)
48 | #_ (when new-iso
49 | (say-delay 1 :main-watch-pre-kill)
50 | (.kill ^Isolate new-iso .priority Isolate.immediate)
51 | ;(.kill ^Isolate new-iso .priority Isolate.beforeNextEvent)
52 | ;; nb: iso debugname still retrievable with either kill priority
53 | (dbgiso :watch-just-killed-iso new-iso)))]
54 | (Isolate.spawn
55 | factorial-worker 5))}
56 | (fx/scaffold
57 | {:appBar (fx/app-bar {:title (fx/text "Intentionally Left Blank (see console)")})})))
--------------------------------------------------------------------------------
/examples/example/demo/isolate/x04_api_mx_iso.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.isolate.x04-api-mx-iso
2 | (:require
3 | ["package:flutter/gestures.dart" :as g]
4 | ["package:flutter/material.dart" :as m
5 | :refer [Canvas Size]]
6 | ["package:flutter/painting.dart" :as p]
7 | ["package:vector_math/vector_math_64.dart" :as vm]
8 | ["dart:math" :as math
9 | :refer [pi cos sin]]
10 | ["dart:async" :as async
11 | :refer [Completer StreamSubscription]]
12 | ["dart:isolate" :as di
13 | :refer [Isolate SendPort ReceivePort]]
14 |
15 | [tilton.mx.api :as md]
16 | [tilton.mx.cell.base :as cb]
17 | [tilton.mx.api :as mx
18 | :refer [dp dpx cI cF cF+ cF+n cFn cFonce mget mget? mset! mswap! minfo fasc fasc-inc
19 | fmu muv fm* mav mx-bound? wmx-iso with-cc]]
20 | [tilton.fmx.api :as fx]
21 | [example.demo.isolate.common :as cmn
22 | :refer [clock-face slow-is-prime? ]]))
23 |
24 | (defn make-app []
25 | (let [title "MX Iso 4 Clock"]
26 | (fx/material-app
27 | {:title title}
28 | {:name :app
29 | :fact-iso (cF (let [the-app me]
30 | (fx/make-isolate
31 | ;; worker
32 | (fn [{:keys [msg-type of-integer] :as task}]
33 | (case msg-type
34 | :compute-factorial (let [r (atom 1)]
35 | (doseq [i (range 1 (inc of-integer))] (swap! r * i))
36 | {:of-integer of-integer
37 | :factorial @r})
38 | (dp :WORKER-UNEXPECTED-TASK!!!!!!!)))
39 | ;; result handler omitted; mx-iso value gets result
40 | )))}
41 | (fx/scaffold
42 | {:appBar (fx/app-bar {:title (fx/text title)})
43 | :floatingActionButton (fx/floating-action-button
44 | {:onPressed (fx/dart-cb []
45 | (wmx-iso
46 | (let [fo (fmu :facto-display)]
47 | (dp :bumping-of!!!! (minfo fo))
48 | (mswap! fo :of + 2))))
49 | :tooltip "Send msg"})}
50 | (fx/column
51 | {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly}
52 | (clock-face)
53 |
54 | (fx/text {}
55 | {:name :facto-display
56 | :of (cI 1 :watch (fn [_ me new-val _ _]
57 | (when-let [iso (mav :fact-iso)]
58 | (when-let [tasko (mget iso :task-out-port)]
59 | ; now we have a pipe to the worker, and can send it our one task: 7
60 | (.send ^SendPort tasko
61 | {:msg-type :compute-factorial
62 | :of-integer new-val})))))}
63 | (str "The factorial of " (mget me :of) " ... "))
64 | (fx/text {}
65 | {:name :mx-iso-display}
66 | (let [mxi (muv :app :fact-iso)]
67 | (str "... is "
68 | (:factorial (mget mxi :value))))))))))
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/examples/example/demo/navigation/component.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.navigation.component
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | [clojure.string :as str]
6 | [tilton.mx.model.base :refer [md-cell md-install-cell md-awaken]]
7 | [tilton.mx.api :refer [dp minfo cF cFI cF+ cI cFn cFonce mmx-md mget mset! mswap! navig fm* fmu fasc mav] :as mx]
8 | [tilton.fmx.api :as fx
9 | :refer [dart-cb within-ctx
10 | material-app scaffold app-bar floating-action-button
11 | center column row container text-button text sized-box]]
12 |
13 | [example.demo.navigation.puzzle :as pz
14 | :refer [mk-puzzle pz-structure pz-nvg-options]]))
15 |
16 | (defn nvg-solution []
17 | (column
18 | (m/Text "1. Click to select a starting widget. 2. Enter target name or path. 3. Set options. 4. Click FAB.")
19 | (nvg-what)
20 | (nvg-options)))
21 |
22 | (defn nvg-what []
23 | (fx/material
24 | {:elevation 6.0
25 | :color m/Colors.white
26 | :shadowColor m/Colors.black}
27 | (fx/intrinsic-width
28 | (fx/text-field {:autofocus true
29 | :focusNode (m/FocusNode)
30 | :decoration (m/InputDecoration
31 | .hintText "Target?"
32 | .border m.InputBorder/none
33 | .contentPadding (m/EdgeInsets.all 9.0))
34 | :onSubmitted (dart-cb [value]
35 | (let [trimmed (str/trim value)]
36 | (mset! me :value trimmed)))
37 | :controller (cFonce (fx/text-field-controller-basic me))}
38 | {:name :what
39 | :value (cI "")}))))
40 |
41 | (defn nvg-options []
42 | (row {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly
43 | :crossAxisAlignment m/CrossAxisAlignment.start}
44 | (nvg-option :must?)
45 | (nvg-option :me?)
46 | (nvg-option :inside?)
47 | (nvg-option :out)
48 | (nvg-option :out-asc-only)
49 | (nvg-option :dbg)))
50 |
51 | (defn nvg-option [option]
52 | (fx/sized-box {:width 200}
53 | (fx/checkbox-list-tile
54 | {:key (m/ValueKey (name option))
55 | :controlAffinity m/ListTileControlAffinity.leading
56 | :title (m/Text (name option))
57 | :value (cF (option (mav :nvg-options)))
58 | :onChanged (dart-cb [on-off]
59 | (mswap! (mav :nvg-options) option not))})))
--------------------------------------------------------------------------------
/examples/example/demo/navigation/puzzle.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.navigation.puzzle
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | [tilton.mx.foundation :refer [PObserver]]
6 | [tilton.mx.model.peek :refer [Model]]
7 | [tilton.mx.model.base :refer [md-cell md-install-cell md-awaken]]
8 | [tilton.mx.api :as mx
9 | :refer [dp minfo cF cFI cF+ cI cFn cFonce mmx-md mget mset! mswap! navig fm* fmu fasc mav
10 | def-mx-props]]
11 | [tilton.fmx.api :as fx
12 | :refer [dart-cb within-ctx
13 | material-app scaffold app-bar floating-action-button
14 | center column row container text-button text sized-box]]))
15 |
16 | ;;; --- domain -----------------------------------
17 |
18 | (deftype Puzzle []
19 | :extends Model
20 | PObserver
21 | (observe [this prop me new-value prior-value cell]
22 | #_(dp :hand-sees prop :now new-value)))
23 |
24 | (def-mx-props pz- structure start seek nvg-options)
25 |
26 | (defn mk-puzzle [structure]
27 | (mx/make (Puzzle)
28 | :structure structure
29 | :nvg-options {:me? false :inside? false :out true :out-asc-only false :without-dependency? true :must? true
30 | :dbg false}
31 | :start (cI nil)
32 | :seek (cI nil)))
33 |
34 | ;;; --- puzzles -------------------------------------------
35 |
36 | (def pzl-zero [[:app {:a 1 :b "2"}]
37 | [[[:scaffy {:c 3
38 | :appBar [:bar {:title "Moby"
39 | :bgColor "red"}]}]
40 | [:body]] :bogus]])
41 |
42 | #_[:app [:scaffy [[[:app-bar {:p0 42 :p1 "red"}] [:aaa :bbb [:ccc [:dddd :eeee :ffff]]]]
43 | #_#_[:body [[:aa [:aaa]]
44 | [:aa [:aaa]]
45 | :bbb]]
46 | [:drawer [[:aa [:aaa]]
47 | [:aa [:aaa]]
48 | :bbb]]
49 | #_:fab]]]
--------------------------------------------------------------------------------
/examples/example/demo/parrot/poetry.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.parrot.poetry
2 | (:require
3 | [clojure.string :as str]))
4 |
5 | (def graves-reproach-s1
6 | (str ;; "\"Reproach\"\n\nby Robert Graves\n\n"
7 | "Your grieving moonlight face looks down\n"
8 | "Through the forest of my fears,\n"
9 | #_#_ "Crowned with a spiny bramble-crown,\n"
10 | "Dew-dropped with evening tears.\n"))
11 |
12 | (def graves-reproach-s2
13 | (str "The black trees shudder, dropping snow,\n"
14 | "The stars tumble and spin.\n"
15 | "Speak, speak, or how may a child know\n"
16 | "His ancestral sin?\n"))
17 |
18 | (def frost-reluctance
19 | (str ;"\"Reluctance\"\n\nby Robert Frost\n\n"
20 | "Ah, when to the heart of man\n"
21 | "Was it ever less than a treason,\n"
22 | "To go with the drift of things,\n"
23 | "To yield with a grace to reason,\n"
24 | "Or acquiesce to the end\n"
25 | "Of a love or a season?\n"))
26 |
27 | (def yeats-second-coming
28 | (str ;"\"The Second Coming\"\nby William Butler Yeats\n\n"
29 | "Turning and turning in the widening gyre\n"
30 | "The falcon cannot hear the falconer;\n"
31 | "Things fall apart; the centre cannot hold;\n"
32 | "Mere anarchy is loosed upon the world.\n"))
33 |
34 | (def graves-jealousy
35 | (str ;"\"Jealousy\"\n\nby Robert Graves\n\n"
36 | "I'd die for you, or you for me, \n"
37 | "So furious is our jealousy-- \n"
38 | "And if you doubt this to be true, \n"
39 | "Kill me outright, lest I kill you.\n"))
40 |
41 | (def carroll-jabberwocky
42 | (str ;"\"Jabberwocky\"\n\nby Lewis Carroll\n\n"
43 | "’Twas brillig, and the slithy toves\n"
44 | "Did gyre and gimble in the wabe:\n"
45 | "All mimsy were the borogoves,\n"
46 | "And the mome raths outgrabe.\n"))
47 |
48 | (def lincoln-gettysburgh
49 | (str ;"\"Gettysburgh Address\n\nAbraham Lincoln\n\n"
50 | ;"The brave men, living and dead,\n"
51 | ;"Who struggled here have consecrated it,\n"
52 | ;"Far above our poor power to add or detract.\n"
53 | "The world will little note,\n"
54 | "Nor long remember what we say here,\n"
55 | "But it can never forget what they did here.\n"))
56 |
57 | (def shakespeare-sonnet-24
58 | (str ;"\"Sonnet 24\"\n\nWilliam Shakespeare\n\n"
59 | "Mine eye hath played the painter\n"
60 | "And hath stell’d thy beauty's form\n"
61 | "In table of my heart.\n"))
--------------------------------------------------------------------------------
/examples/example/demo/parrot/stt/common.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.parrot.stt.common
2 | (:require
3 | ["package:speech_to_text/speech_to_text.dart" :as stt]))
4 |
5 | (def ^stt/SpeechToText STT (stt/SpeechToText))
--------------------------------------------------------------------------------
/examples/example/demo/parrot/stt/core.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.parrot.stt.core
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | ["package:flutter/widgets.dart" :as w]
6 | ;
7 | ["package:speech_to_text/speech_to_text.dart" :as stt]
8 | ["package:speech_to_text_platform_interface/speech_to_text_platform_interface.dart" :as sttpi]
9 | ["package:speech_to_text/speech_recognition_error.dart" :as stte]
10 | ["package:speech_to_text/speech_recognition_result.dart" :as sttr]
11 |
12 | [clojure.string :as str]
13 | [tilton.mx.api :as mx
14 | :refer [dp dpx cI cF cF+ cF+n cFn cFonce mget mget? mset! mswap! minfo fasc fasc-inc
15 | fmu muv fm* mav mx-bound? wmx-iso]]
16 | [tilton.fmx.api :as fx
17 | :refer [scaffold app-bar text center column hero material-app
18 | container row expanded icon padding opacity ignore-pointer
19 | checkbox-list-tile icon-button fx-render dart-cb]]
20 | [example.demo.parrot.stt.common :as cmn]))
21 |
22 | ; todo: move to mx api
23 | (defmacro try-wmx-iso [& body]
24 | `(try
25 | (tilton.mx.api/wmx-iso ~@body)
26 | (catch Exception e#
27 | (dp :FLUTTERCATCH!! e#))))
28 |
29 | (defn sp-initializer-rule []
30 | (cF+ [:async? true
31 | :watch (fn [_ me new _ _]
32 | (dpx :initialized? new)
33 | (when new
34 | (dpx :post-init-avail (.-isAvailable cmn/STT))
35 | (dpx :post-init-listening (.-isListening cmn/STT))
36 | (dpx :post-init-has-error (.-hasError cmn/STT))
37 | (when new
38 | (try-wmx-iso
39 | (mset! me :sp-status :available)))))]
40 | (.initialize cmn/STT
41 | .onStatus (fn [status]
42 | (try-wmx-iso
43 | (dp :onStatus-sets-status (keyword status))
44 | (mset! me :sp-status (keyword status))))
45 | .onError (fn [^stte/SpeechRecognitionError err]
46 | (dp :sp-error!!!!! (.-errorMsg err))
47 | (try-wmx-iso
48 | (mset! me :transcript (str "Error: " (.-errorMsg err))))))))
49 |
50 | (defn stop-listening [me]
51 | (dpx :requesting-stop)
52 | (.stop cmn/STT))
53 |
54 |
55 |
--------------------------------------------------------------------------------
/examples/example/demo/todoMVC/common.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.todoMVC.common
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | [tilton.mx.base :refer [dprn dp dpx]]))
5 |
6 | (defn title-red []
7 | (.fromRGBO m/Color 184 63 69 0.5))
8 |
9 | (defmacro my-todo-list []
10 | `(tilton.mx.model.base/mget
11 | (tilton.mx.model.core/fasc :app)
12 | :todo-list))
--------------------------------------------------------------------------------
/examples/example/demo/todoMVC/persist.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.todoMVC.persist
2 | (:require
3 | ["package:hive_flutter/hive_flutter.dart" :as hv]
4 | ["dart:convert" :as convert]
5 | ["package:uuid/uuid.dart" :as uu]
6 | [tilton.mx.util :as util]
7 | [clojure.walk :as walk]))
8 |
9 | (def +DB+ (atom nil)) ;; n.b. just a cache, NOT reactive
10 | (defn ^hv/Box? DB [] (deref +DB+))
11 | (defn ^hv/Box? DB! [db] (reset! +DB+ db))
12 |
13 | (def +uuid+ (atom nil))
14 | (defn ^uu/Uuid UUID []
15 | (or (deref +uuid+)
16 | (uu/Uuid)))
17 |
18 | (defn td-store
19 | "Write a CLJD ToDo map to persistent storage.
20 | Map must contain :stg-id, a string identifier.
21 | Returns the stg-id."
22 | [td-map]
23 | (let [stg-id (:stg-id td-map)]
24 | (assert stg-id "td-rewrite map must include stg-id")
25 | (.put (DB) stg-id
26 | (convert/jsonEncode
27 | (walk/stringify-keys
28 | (select-keys td-map
29 | [:stg-id :created-at :title :completed]))))
30 | stg-id))
31 |
32 | (defn td-initialize
33 | "Create a Hive to-do from a CLJD map alone.
34 | Returns the unique storage key generated for the data."
35 | [collection-name td-map]
36 | (when-let [stg-id (:stg-id td-map)]
37 | (throw (Exception. (str "td-initialize> sees :stg-id " stg-id ", suggesting td already written"))))
38 |
39 | (let [new-stg-id (str collection-name "/" (.v4 (UUID)))]
40 | (td-store
41 | (assoc td-map :stg-id new-stg-id))
42 | new-stg-id))
43 |
44 | (defn td-rewrite
45 | "Update a stored to-do given only a CLJD map of its properties.
46 | Map must contain non-nil :stg-id."
47 | [td-map]
48 | (assert (:stg-id td-map)
49 | "td-rewrite> map must include stg-id")
50 | (td-store td-map)
51 | (:stg-id td-map))
52 |
53 | (defn td-delete
54 | "Deletes storage associated with stg-id."
55 | [stg-id]
56 | (assert stg-id "td-delete> stg-id argument is nil. s/b string ID.")
57 | (.delete (DB) stg-id)
58 | stg-id)
59 |
60 | ;;; --- collection-level utilities -------------
61 |
62 | (defn collection-docs [collection-name]
63 | (let [all-td-keys (collection-keys collection-name)]
64 | (mapv (fn [td-key]
65 | (util/dart-map->cljd-map
66 | (convert/jsonDecode (.get (DB) td-key))))
67 | all-td-keys)))
68 |
69 | (defn collection-keys [collection-name]
70 | (into #{} (.-keys (DB))))
71 |
72 | (defn collection-delete-all [collection-name]
73 | (doseq [k (collection-keys collection-name)]
74 | (td-delete k)))
--------------------------------------------------------------------------------
/examples/example/demo/todoMVX/README.md:
--------------------------------------------------------------------------------
1 | # TodoMVX: TodoMVC via Flutter, ColureDart, Matrix, and Supabase
2 |
3 | Programming [Flutter](https://flutter.dev/?gclid=CjwKCAjwwdWVBhA4EiwAjcYJEEoxUuE14sd2MGLJW35qeuJynmTRjqpUL3SbIUhOiS4TihjyZ9iTVRoCJkoQAvD_BwE&gclsrc=aw.ds) with [ClojureDart](https://github.com/Tensegritics/ClojureDart), [Matrix](https://github.com/kennytilton/matrix), a generic, fine-grained, transparent, reactive state manager, and Supabase.
4 |
5 | #### PREREQUISITES
6 |
7 | To run this example, we have to:
8 | 1. create a free account on Supabase;
9 | 2. define a project called "to-do";
10 | 3. create a table for to-dos:
11 | ```postgresql
12 | -- Table: public.to-do
13 |
14 | -- DROP TABLE IF EXISTS public."to-do";
15 |
16 | CREATE TABLE IF NOT EXISTS public."to-do"
17 | (
18 | created_at timestamp with time zone NOT NULL DEFAULT now(),
19 | title text COLLATE pg_catalog."default" NOT NULL,
20 | due_by timestamp with time zone,
21 | completed boolean NOT NULL DEFAULT false,
22 | uid uuid NOT NULL DEFAULT gen_random_uuid(),
23 | CONSTRAINT "to-do_pkey" PRIMARY KEY (uid),
24 | CONSTRAINT "to-do_uid_key" UNIQUE (uid)
25 | )
26 |
27 | TABLESPACE pg_default;
28 |
29 | ALTER TABLE IF EXISTS public."to-do"
30 | OWNER to postgres;
31 |
32 | GRANT ALL ON TABLE public."to-do" TO anon;
33 |
34 | GRANT ALL ON TABLE public."to-do" TO authenticated;
35 |
36 | GRANT ALL ON TABLE public."to-do" TO postgres;
37 |
38 | GRANT ALL ON TABLE public."to-do" TO service_role;
39 |
40 | COMMENT ON TABLE public."to-do"
41 | IS 'TodoMVC Classic';
42 | ```
43 | 3. get the project URL and secret key and create nvars in your login script:
44 | * `export SUPA_MVX_URL=""`
45 | * `export SUPA_MVX_KEY=""`
46 | 4. run like this, a bash script easiest:
47 | ``` bash
48 | clj -M:cljd flutter --dart-define=SUPA_MVX_URL=$SUPA_MVX_URL \
49 | --dart-define=SUPA_MVX_KEY=$SUPA_MVX_KEY
50 | ```
51 | 5. add `-d chrome` to run on the web; and
52 | 6. Finally, certain entitlements are required to access Supabase via HTTP Edit the `Runnner>Runner>DebugProfile` and edit `Entitlements file`, adding:
53 | * com.apple.security.network.server
54 | 7. Do the same with `R>R>Release` if one is planned.
55 |
56 |
57 | Ping @kennytilton on #clojurians Slack for help!
58 |
--------------------------------------------------------------------------------
/examples/example/demo/todoMVX/common.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.todoMVX.common
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | [tilton.mx.base :refer [dprn dp dpx]]
5 | [tilton.mx.api :as mx]))
6 |
7 | (defn title-red []
8 | (.fromRGBO m/Color 184 63 69 0.5))
9 |
10 |
11 | (defn app-now []
12 | (mx/now-ms))
13 |
14 | (defn app-now-utc []
15 | (.toString (.fromMillisecondsSinceEpoch DateTime (app-now)
16 | .isUtc true)))
17 |
18 |
19 | (defmacro my-todo-list [& [me]]
20 | `(let [me# ~(or me 'me)]
21 | (tilton.mx.model.base/mget
22 | (tilton.mx.model.core/fasc :app me#)
23 | :todo-list)))
24 |
25 | (defmacro my-todos []
26 | `(tilton.mx.api/mkids (example.demo.todoMVX.common/my-todo-list)))
27 |
28 | (defmacro my-todo-add [title]
29 | `(let [list# (example.demo.todoMVX.common/my-todo-list)]
30 | (tilton.mx.api/mswap! list# :kids conj
31 | (example.demo.todoMVX.common/make-ToDo list#
32 | ~title))))
--------------------------------------------------------------------------------
/examples/example/demo/todoMVX/persist.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.todoMVX.persist
2 | (:require
3 | ["package:hive_flutter/hive_flutter.dart" :as hv]
4 | ["dart:convert" :as convert]
5 | ["package:uuid/uuid.dart" :as uu]
6 | [tilton.mx.util :as util]
7 | [clojure.walk :as walk]))
8 |
9 | (def +DB+ (atom nil)) ;; n.b. just a cache, NOT reactive
10 | (defn ^hv/Box? DB [] (deref +DB+))
11 | (defn ^hv/Box? DB! [db] (reset! +DB+ db))
12 |
13 | (def +uuid+ (atom nil))
14 | (defn ^uu/Uuid UUID []
15 | (or (deref +uuid+)
16 | (uu/Uuid)))
17 |
18 | (defn td-store
19 | [td-map]
20 | (let [uid (:uid td-map)]
21 | (assert uid "td-rewrite map must include uid")
22 | (.put (DB) uid
23 | (convert/jsonEncode
24 | (walk/stringify-keys
25 | (select-keys td-map
26 | [:uid :created-at :title :completed]))))
27 | uid))
28 |
29 | (defn td-initialize
30 | "Create a Hive to-do from a CLJD map alone.
31 | Returns the unique storage key generated for the data."
32 | [collection-name td-map]
33 | (when-let [uid (:uid td-map)]
34 | (throw (Exception. (str "td-initialize> sees :uid " uid ", suggesting td already written"))))
35 |
36 | (let [new-uid (str collection-name "/" (.v4 (UUID)))]
37 | (td-store
38 | (assoc td-map :uid new-uid))
39 | new-uid))
40 |
41 | (defn td-rewrite
42 | "Update a stored to-do given only a CLJD map of its properties.
43 | Map must contain non-nil :uid."
44 | [td-map]
45 | (assert (:uid td-map)
46 | "td-rewrite> map must include uid")
47 | (td-store td-map)
48 | (:uid td-map))
49 |
50 | (defn td-delete
51 | "Deletes storage associated with uid."
52 | [uid]
53 | (assert uid "td-delete> uid argument is nil. s/b string ID.")
54 | (.delete (DB) uid)
55 | uid)
56 |
57 | ;;; --- collection-level utilities -------------
58 |
59 | (defn collection-docs [collection-name]
60 | (let [all-td-keys (collection-keys collection-name)]
61 | (mapv (fn [td-key]
62 | (util/dart-map->cljd-map
63 | (convert/jsonDecode (.get (DB) td-key))))
64 | all-td-keys)))
65 |
66 | (defn collection-keys [collection-name]
67 | (into #{} (.-keys (DB))))
68 |
69 | (defn collection-delete-all [collection-name]
70 | (doseq [k (collection-keys collection-name)]
71 | (td-delete k)))
--------------------------------------------------------------------------------
/examples/example/demo/todoMVX/supa.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.todoMVX.supa
2 | (:require
3 | ["dart:convert" :as convert]
4 | ["package:uuid/uuid.dart" :as uu]
5 | ["package:supabase_flutter/supabase_flutter.dart" :as supabase]
6 | [tilton.mx.api :as mx
7 | :refer [dp dpx mget mget? mset! mswap! fasc cF cF+ cI]]
8 | [clojure.string :as str]))
9 |
10 |
11 | (defn stg-upsert [table table-props me] ;; a model, such as light from make-Light
12 | (dpx :STGupsert-sees table-props (mget? me :created_at)(mget? me :created-at))
13 | (let [op (-> supabase/Supabase.instance.client
14 | (.from table)
15 | (.upsert (into {} (for [prop table-props]
16 | [(str/replace (name prop) #"-" "_")
17 | (mget me prop)]))))]
18 | (dpx :upsert!!!!! op (dart/is? op Future))
19 | (await op) ;; effects the write
20 | (mget me :uid)))
21 |
22 | (defn stg-rewrite [table table-props me] ;; a model, such as light from make-Light
23 | (dpx :stg-rewriting (mx/minfo me))
24 | (stg-upsert table table-props me)
25 | (mget me :uid))
26 |
27 | (defn stg-insert [table table-props props] ;; a model, such as light from make-Light
28 | (dp :STGINSERT-entry table table-props props)
29 | (let [row (into {} (for [prop table-props]
30 | [(str/replace (name prop) #"-" "_") ;; can't hurt if we never force hyphens on pg
31 | (get props prop)]))]
32 | ;(dp :STGIN-ACTUAL-row table row)
33 | (let [fop (-> supabase/Supabase.instance.client
34 | (.from table)
35 | (.insert row)
36 | .select)]
37 | (let [props (atom (await fop))]
38 | (deref props)))))
39 |
40 | (defn stg-delete
41 | "Deletes storage associated with uid."
42 | [table uid]
43 | (assert uid (str "stg-delete> " table " uid argument is nil. s/b string ID."))
44 | (let [op (-> supabase/Supabase.instance.client
45 | (.from table)
46 | .delete
47 | (.match {"uid" uid}))]
48 | (await op)
49 | uid))
--------------------------------------------------------------------------------
/examples/example/demo/todoMVX/todoMVX.sql:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/examples/example/demo/todoMVX/todoMVX.sql
--------------------------------------------------------------------------------
/examples/example/demo/tts/core.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.tts.core
2 | "Originally, a straught port of the `flutter_tts` package example https://github.com/dlutton/flutter_tts/blob/master/example/lib/main.dart"
3 | (:require
4 | ["package:flutter/material.dart" :as m]
5 | ["package:flutter/painting.dart" :as p]
6 | ["package:flutter_tts/flutter_tts.dart" :as fts
7 | :refer [FlutterTts]]
8 | ["package:flutter/widgets.dart" :as w]
9 | [clojure.string :as str]
10 | [tilton.mx.api :as mx
11 | :refer [dp dpx cI cF cF+ cF+n cFn cFonce mget mget? mset! mswap! minfo fasc fasc-inc
12 | fmu muv fm* mav mx-bound? wmx-iso]]
13 | [tilton.fmx.api :as fx
14 | :refer [scaffold app-bar text center column hero material-app
15 | container row expanded icon padding opacity ignore-pointer
16 | checkbox-list-tile icon-button fx-render dart-cb]]
17 | [example.demo.tts.fts :as fts
18 | :refer [app-fts-progress app-fts-status]]
19 | [example.demo.tts.component
20 | :refer [lang-chooser geo-chooser voice-chooser play-pause-button stop-button auto-play
21 | equalizer choice-header]]
22 | [example.demo.tts.poetry :as poetry]))
23 |
24 | ;;; === app ======================================================
25 | (declare dashboard speech-input)
26 |
27 | (defn chyron []
28 | (container
29 | {:padding (m/EdgeInsets.symmetric .horizontal 16.0)}
30 | (fx/text {:textAlign m/TextAlign.center}
31 | {:phrase (cF+ [:sst nil]
32 | (when (not= :off (app-fts-status))
33 | (let [{:keys [word]} (app-fts-progress)]
34 | (if (nil? word) []
35 | (take-last 5
36 | (concat (if (mx-bound? _cache) _cache [])
37 | [word]))))))}
38 | (str/join "..." (mget me :phrase)))))
39 |
40 | (defn make-app []
41 | (material-app {}
42 | {:name :app
43 | :fts (cF (fts/make-flutter-tts))}
44 | (scaffold
45 | {:appBar (app-bar {:title (m/Text "Flutter TTS Demo")})}
46 | (column
47 | {:crossAxisAlignment m/CrossAxisAlignment.stretch}
48 | (choice-header "Languages")
49 | (lang-chooser)
50 | (choice-header "Geography")
51 | (geo-chooser)
52 | (choice-header "Voices")
53 | (voice-chooser)
54 | (choice-header "Script")
55 | (speech-input poetry/graves-jealousy)
56 | (chyron)
57 | (dashboard)
58 | (auto-play)
59 | (equalizer)))))
60 |
61 | ;;; --- dashboard ---------------------------------------------------------------
62 |
63 | (defn dashboard []
64 | (container {:padding (m/EdgeInsets.only .top 8 .bottom 8)}
65 | (row {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly}
66 | (play-pause-button)
67 | (stop-button))))
68 |
69 | ;;; --- text input --------------------------------------------------------------
70 |
71 | (defn speech-input [speech-initial]
72 | (container
73 | {:alignment m/Alignment.topCenter
74 | :padding (m/EdgeInsets.only
75 | .top 25.0 .left 25.0 .right 25.0 .bottom 9)}
76 | (fx/text-field
77 | {:style (p/TextStyle
78 | .fontFamily "Helvetica Neue"
79 | .fontSize 20.0)
80 | :controller (cFonce
81 | (m/TextEditingController .text (mget me :value)))
82 | :onChanged (dart-cb [text]
83 | (mset! me :value text))
84 | :minLines 6 :maxLines 11}
85 | {:name :text-in
86 | :value (cI speech-initial)})))
87 |
88 |
--------------------------------------------------------------------------------
/examples/example/demo/tts/poetry.cljd:
--------------------------------------------------------------------------------
1 | (ns example.demo.tts.poetry
2 | (:require
3 | [clojure.string :as str]))
4 |
5 | (def graves-reproach-s1
6 | (str ;; "\"Reproach\"\n\nby Robert Graves\n\n"
7 | ;"Your grieving moonlight face looks down\n"
8 | "Through the forest of my fears,\n"
9 | "Crowned with a spiny bramble-crown,\n"
10 | "Dew-dropped with evening tears.\n"))
11 |
12 | (def graves-reproach-s2
13 | (str "The black trees shudder, dropping snow,\n"
14 | "The stars tumble and spin.\n"
15 | "Speak, speak, or how may a child know\n"
16 | "His ancestral sin?\n"))
17 |
18 | (def frost-reluctance
19 | (str ;"\"Reluctance\"\n\nby Robert Frost\n\n"
20 | "Ah, when to the heart of man\n"
21 | "Was it ever less than a treason,\n"
22 | "To go with the drift of things,\n"
23 | "To yield with a grace to reason,\n"
24 | "Or acquiesce to the end\n"
25 | "Of a love or a season?\n"))
26 |
27 | (def yeats-second-coming
28 | (str ;"\"The Second Coming\"\nby William Butler Yeats\n\n"
29 | "Turning and turning in the widening gyre\n"
30 | "The falcon cannot hear the falconer;\n"
31 | "Things fall apart; the centre cannot hold;\n"
32 | "Mere anarchy is loosed upon the world.\n"))
33 |
34 | (def graves-jealousy
35 | (str ;"\"Jealousy\"\n\nby Robert Graves\n\n"
36 | "I'd die for you, or you for me, \n"
37 | "So furious is our jealousy-- \n"
38 | "And if you doubt this to be true, \n"
39 | "Kill me outright, lest I kill you.\n"))
40 |
41 | (def carroll-jabberwocky
42 | (str ;"\"Jabberwocky\"\n\nby Lewis Carroll\n\n"
43 | "’Twas brillig, and the slithy toves\n"
44 | "Did gyre and gimble in the wabe:\n"
45 | "All mimsy were the borogoves,\n"
46 | "And the mome raths outgrabe.\n"))
47 |
48 | (def lincoln-gettysburgh
49 | (str ;"\"Gettysburgh Address\n\nAbraham Lincoln\n\n"
50 | ;"The brave men, living and dead,\n"
51 | ;"Who struggled here have consecrated it,\n"
52 | ;"Far above our poor power to add or detract.\n"
53 | "The world will little note,\n"
54 | "Nor long remember what we say here,\n"
55 | "But it can never forget what they did here.\n"))
56 |
57 | (def shakespeare-sonnet-24
58 | (str ;"\"Sonnet 24\"\n\nWilliam Shakespeare\n\n"
59 | "Mine eye hath played the painter\n"
60 | "And hath stell’d thy beauty's form\n"
61 | "In table of my heart.\n"))
--------------------------------------------------------------------------------
/examples/example/eg/flutter_layout_tutorial.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.flutter-layout-tutorial
2 | "Port of Dave Liepmann's ClojureDart port https://github.com/daveliepmann/ClojureDart/tree/main/samples/flutter_tutorial_building_layouts
3 | of Flutter 'Building layouts' tutorial https://docs.flutter.dev/ui/layout/tutorial"
4 | (:require
5 | ["package:flutter/material.dart" :as m]
6 | ["package:flutter/painting.dart" :as p]
7 | [clojure.string :as str]
8 | [tilton.mx.api :refer [ dp dpx cF cF+ cI mget mswap! mset! mav fasc fm* muv fmu minfo] :as mx]
9 | [tilton.fmx.api :as fx
10 | :refer [scaffold app-bar text center column hero material-app
11 | container row expanded icon padding within-ctx]]))
12 |
13 | (defn make-app []
14 | (let [title "Flutter layout demo (cljd-ified!)"]
15 | (material-app
16 | {:title title}
17 | (scaffold
18 | {:appBar (app-bar {:title (text title)})}
19 | (column
20 | (m/Image.asset "image/lake-oeschinen.jpeg"
21 | .width 600 .height 240
22 | .fit m/BoxFit.cover)
23 |
24 | (title-section)
25 |
26 | (fx/builder ;; supplies extra context to support Theme.of
27 | (row {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly}
28 | (into [] (for [[ico label] [[m/Icons.call "CALL"]
29 | [m/Icons.near_me "ROUTE"]
30 | [m/Icons.share "SHARE"]]]
31 | (button-column (within-ctx [me ctx]
32 | (.-primaryColor (m/Theme.of ctx)))
33 | ico label)))))
34 |
35 | (padding {:padding (m/EdgeInsets.all 32)}
36 | (text {:softWrap true}
37 | (campground-desc))))))))
38 |
39 | ;;; --- sections ------------------------------------------------------
40 |
41 | (defn title-section []
42 | (container
43 | {:padding (m/EdgeInsets.all 32)}
44 | (row
45 | (expanded
46 | (column {:crossAxisAlignment m/CrossAxisAlignment.start}
47 | (container {:padding (m/EdgeInsets.only .bottom 8)}
48 | (text {:style (m/TextStyle .fontWeight m/FontWeight.bold)}
49 | "Oeschinen Lake Campground"))
50 | (text {:style (m/TextStyle .color (m/Colors.grey 500))}
51 | "Kandersteg, Switzerland")))
52 | (fx/icon {:color (m/Colors.red 500)}
53 | m/Icons.star)
54 | (text "41"))))
55 |
56 | (defn button-column [color icon label]
57 | (column {:mainAxisSize m/MainAxisSize.min
58 | :mainAxisAlignment m/MainAxisAlignment.center}
59 | {:name :button-col}
60 | (fx/icon {:color color} icon)
61 | (container {:margin (m/EdgeInsets.only .top 8)}
62 | (text {:style (fx/text-style {:fontSize 12
63 | :fontWeight m/FontWeight.w400
64 | :color color})}
65 | label))))
66 |
67 | (defn campground-desc []
68 | (str/replace
69 | "Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese Alps.
70 | Situated 1,578 meters above sea level, it is one of the larger Alpine Lakes.
71 | A gondola ride from Kandersteg, followed by a half-hour walk through pastures
72 | and pine forest, leads you to the lake, which warms to 20 degrees Celsius in the summer.
73 | Activities enjoyed here include rowing, and riding the summer toboggan run."
74 | #"\n" ""))
75 |
76 |
--------------------------------------------------------------------------------
/examples/example/eg/x00_hello_world.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x00-hello-world
2 | (:require
3 | [clojure.string :as str]
4 | [tilton.mx.api :refer [cF mget mset! mswap!] :as md]
5 | [tilton.fmx.factory :refer [deftag] :as fxf]
6 | [tilton.fmx.api :as fx
7 | :refer [scaffold app-bar text center column hero material-app]]
8 | ["package:flutter/widgets.dart" :as w]
9 | ["package:flutter/material.dart" :as m]
10 | ["package:flutter/painting.dart" :as p]))
11 |
12 | (deftag fxf/non-widget theme-data m/ThemeData)
13 | (deftag fxf/kidless-childless image w/Image )
14 |
15 | ;(deftag fxf/kidless-childless asset-image p/AssetImage )
16 | ; no, this has to be konly-param0 or sth
17 |
18 | (defn make-app []
19 | (material-app
20 | {:title "Flutter/MX Hello Teal World"
21 | :theme (cF (theme-data
22 | {:primarySwatch (let [ttl (mget me :title)]
23 | ;; silly derivation
24 | (cond
25 | (str/includes? ttl "Teal") m/Colors.teal
26 | (str/includes? ttl "Red") m/Colors.red
27 | :else m/Colors.blue))}))}
28 | (scaffold
29 | {:appBar (app-bar
30 | {:title (m/Text "Welcome to Flutter/MX")})}
31 | (center
32 | (column
33 | {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly}
34 | (text {:overflow p.TextOverflow/ellipsis
35 | :style (fx/text-style {:fontSize 40
36 | :fontWeight m/FontWeight.w600
37 | :color m/Colors.blue})}
38 | "hello, world\\n")
39 | (hero {:tag "imageHero"}
40 | (image {:image (m/AssetImage "image/kernighan.jpeg")
41 | :height 512}))
42 | (text {:overflow p.TextOverflow/ellipsis
43 | :style (fx/text-style {:fontSize 20
44 | :fontWeight m/FontWeight.w400
45 | :color m/Colors.blue})}
46 | "Brian Kernighan"))))))
--------------------------------------------------------------------------------
/examples/example/eg/x01_counter.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x01-counter
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/painting.dart" :as p]
5 | [tilton.mx.model.base :refer [md-cell md-install-cell md-awaken]]
6 | [tilton.mx.api :refer [dp minfo cF cF+ cI cFn cFonce mmx-md mget mset! mswap! fm* fmu fasc mav] :as mx]
7 | [tilton.fmx.api :as fx
8 | :refer [dart-cb within-ctx
9 | material-app scaffold app-bar floating-action-button
10 | center column text sized-box]]))
11 |
12 | (defn make-app []
13 | (material-app
14 | {:title "Flutter/MX Counter Demo"
15 | :theme (m/ThemeData .useMaterial3 true
16 | .colorScheme (m/ColorScheme.fromSeed
17 | .seedColor m/Colors.deepPurple))}
18 | (scaffold
19 | {:appBar (app-bar
20 | {:title (m/Text "Flutter/MX Counter")
21 | :backgroundColor (cF (.-inversePrimary
22 | (.-colorScheme ^m/ThemeData (mav :theme))))})
23 | :floatingActionButton (floating-action-button
24 | {:onPressed (dart-cb []
25 | (mswap! (fm* :counter) :value inc))
26 | :tooltip "Increment"}
27 | (m/Icon m/Icons.add .color m/Colors.black))}
28 | (center
29 | (column {:mainAxisAlignment m/MainAxisAlignment.center}
30 | (text {:style (-> (m/Theme.of (fx/*ctx)) .-textTheme .-displaySmall)
31 | ;;; this silliness is a test to see if the engine can propagate to setState
32 | ;; when the reactivity is embedded in a delegate model, the text-style. So far so good.
33 | ;; If it fails, try just wrapping the non-updating widget in `(fx/stateful-builder....)`
34 | #_(cF (fx/text-style
35 | {:color m/Colors.black
36 | :fontSize (cF (+ 24.0 (* 1.0 (mget (fm* :counter) :value))))}))}
37 | "Button push count:")
38 | (sized-box
39 | {:height 28.0})
40 | (text
41 | {:style (-> (m/Theme.of (fx/*ctx)) .-textTheme .-displayMedium)}
42 | {:name :counter
43 | :value (cI 0)}
44 | (str (mget me :value))))))))
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/examples/example/eg/x01_counter_desugared.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x01-counter-desugared
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | [tilton.mx.api :refer [dp dpx minfo mmx-md cI cF mget mswap! fm* fasc] :as mx]
5 | [tilton.fmx.factory :refer [deftag deftags] :as fxf]
6 | [tilton.fmx.api :as fx
7 | :refer [dart-cb within-ctx
8 | app-bar floating-action-button
9 | theme icon-theme center column text sized-box]]))
10 |
11 | ;;; --- The Flutter Classic: A Counter App -----------------------
12 | ;;; A straight transliteration from the Dart example Counter app
13 | ;;;
14 | ;;; Note that, unlike the Dart original, this is not one big widget.
15 | ;;; Each different widget below has its own build method and responds
16 | ;;; to a different setState.
17 |
18 | ;;; Here we override the usual sugared widgets that take common
19 | ;;; attributes such as :home and :body from a solo (implicit) child
20 | ;;; with widgets that work closer to the Flutter, and make the properties explicit.
21 |
22 | (deftags tilton.fmx.factory/kidless-childless
23 | (material-app m/MaterialApp)
24 | (scaffold m/Scaffold))
25 |
26 | (defn make-app []
27 | (material-app
28 | {:title "Flutter/MX Counter Demo"
29 | :theme (m/ThemeData
30 | .colorScheme (m/ColorScheme.fromSeed
31 | .seedColor m/Colors.deepPurple)
32 | .useMaterial3 true)
33 | :home (cF (scaffold
34 | {:appBar (app-bar {:backgroundColor (fx/within-ctx [me ctx]
35 | (.-inversePrimary (.-colorScheme (m/Theme.of ctx))))
36 | :title (m/Text "Flutter/MX Counter Classic")})
37 | :body (cF (center
38 | (column {:mainAxisAlignment m/MainAxisAlignment.center}
39 | (text "You have pushed the button this many times:")
40 | (text
41 | {:style (within-ctx [me ctx]
42 | (.-headlineMedium (.-textTheme (m/Theme.of ctx))))}
43 | (str (mget (fm* :scaffo) :counter))))))
44 | :floatingActionButton (floating-action-button
45 | {:onPressed (dart-cb []
46 | (mswap! (fm* :scaffo) :counter inc))
47 | :tooltip "Increment"}
48 | (m/Icon m/Icons.add))}
49 | {:name :scaffo
50 | :counter (cI 0)}))}))
--------------------------------------------------------------------------------
/examples/example/eg/x029_layout_builder.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x029-layout-builder
2 | (:require
3 | ["dart:math" :as math]
4 | ["package:flutter/widgets.dart" :as w]
5 | ["package:flutter/material.dart" :as m]
6 | ["package:flutter/painting.dart" :as p]
7 | [tilton.mx.api :refer [dp cF cI mget muv] :as mx]
8 | [tilton.fmx.factory :refer [binding-ctx]]
9 | [tilton.fmx.api :refer [within-ctx dart-cb] :as fx]))
10 |
11 | (defn make-app []
12 | (let [title "Layout Builder Dynamic Text Size?"]
13 | (dp :builder-app!! )
14 | (fx/material-app {:title title}
15 | (fx/scaffold
16 | {:appBar (fx/app-bar {:title (fx/text title)})}
17 | (fx/center
18 | (fx/layout-builder
19 | {:builder (fn [ctx box-constraint]
20 | ;; next bit is key: the layout builder wants back a native Flutter
21 | ;; widget, so we have to do the conversion from f/mx proxy to Flutter
22 | ;; ourselves, sth normally midden by f/mx macrology.
23 |
24 | ;; KNOWN BUG:
25 | (dp :builder-runz!! box-constraint)
26 | ;; above output shows repeated rotation does not invoke builder going
27 | ;; from one horizontal (not sure how to define it) to one portait orientation,
28 | ;; so layout does not get rebuilt.
29 |
30 | (binding-ctx :xo2p-builder-exp ctx
31 | (fx/fx-render ctx
32 | ; now we can play in f/mx world....
33 |
34 | (fx/column
35 | (let [height (.-height (.-size (m/MediaQuery.of ctx)))]
36 | ;(dp :x029b-sees-height :mq-height height :ctx (fx/*ctx))
37 | (when (> height 600)
38 | (fx/text
39 | {:style (p/TextStyle
40 | .color m/Colors.blue
41 | .fontSize 24)}
42 | {:name :test}
43 | "Rotate the device or sim to see layout effect.")))
44 | (fx/text
45 | {:style (cF (p/TextStyle
46 | .color (mget me :font-color)
47 | .fontSize (mget me :font-size)))}
48 | {:font-size (* 0.1 (.-maxHeight ^m/BoxConstraints box-constraint))
49 | :font-color (cF (cond
50 | (> (mget me :font-size) 50) m/Colors.red
51 | :else m/Colors.cyan))}
52 | (str "Fontsize " (/ (int (* 10 (mget me :font-size))) 10)))
53 | (fx/text-field {:controller (m/TextEditingController
54 | .text "Hi, Mom.")}
55 | {:name :test-input})))))}))))))
--------------------------------------------------------------------------------
/examples/example/eg/x02_two_counters_ala_flux.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x02-two-counters-ala-flux
2 | "In response to a challenge, we show what it would be like to have
3 | a single map serving as a store, a la Flux."
4 | (:require
5 | [clojure.string :as str]
6 | [tilton.mx.api :refer [dp minfo mav fasc cF cI mget mset! mswap!]]
7 | [tilton.fmx.api :as fx]
8 |
9 | ["package:flutter/widgets.dart"
10 | :refer [Text State StatefulWidget StatelessWidget]]
11 | ["package:flutter/material.dart" :as m
12 | :refer [MainAxisAlignment Colors Theme Icon Icons ThemeData runApp AppBar State]]
13 | ["package:flutter/painting.dart"
14 | :refer [TextStyle]]))
15 |
16 | (defn build-counter [counter-key]
17 | (fx/expanded
18 | (fx/column
19 | {:mainAxisAlignment MainAxisAlignment/center}
20 | {:name counter-key
21 | :counter (cF (get-in (mav :flux-store) [:counters counter-key]))}
22 | (fx/text (str/capitalize (name counter-key)))
23 | (fx/text {:style (TextStyle
24 | .color m/Colors.cyan
25 | .fontSize 32.0)}
26 | {:name :ctr-text}
27 | (str (mav :counter)))
28 | (fx/elevated-button
29 | {:onPressed (fx/dart-cb []
30 | (mswap! (fasc :counter-app)
31 | :flux-store update-in [:counters counter-key] inc))}
32 | (fx/text "+")))))
33 |
34 | (defn make-app []
35 | (fx/material-app
36 | {:title "Two Counters"
37 | :theme (cF (ThemeData .primarySwatch Colors/blue))}
38 | {:name :counter-app
39 | ; simulating a separate global store a la Flux, we bind a purely independent Matrix data structure that
40 | ; must be consulted for values. Pro tip: use `mswap! :flux-store update-in etc` to
41 | ; increment either counter.
42 | :flux-store (cI {:counters {:left 0 :right 0}})}
43 |
44 | (fx/scaffold
45 | {:appBar (fx/app-bar {:title (fx/text "Two Counters ala Flux")})}
46 | (fx/center
47 | (fx/row
48 | {:mainAxisAlignment MainAxisAlignment/center}
49 | (mapv #(build-counter %) [:left :right]))))))
--------------------------------------------------------------------------------
/examples/example/eg/x02_two_counters_ala_matrix.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x02-two-counters-ala-matrix
2 | (:require
3 | ["package:flutter/widgets.dart"
4 | :refer [Text State StatefulWidget StatelessWidget]]
5 | ["package:flutter/material.dart" :as m
6 | :refer [MainAxisAlignment Colors Theme Icon Icons ThemeData runApp AppBar State]]
7 | ["package:flutter/painting.dart"
8 | :refer [TextStyle]]
9 |
10 | [clojure.string :as str]
11 | [tilton.mx.api :refer [cF cI make mget cFkids fmu muv] :as mx]
12 | [tilton.fmx.api :as fx]
13 | ))
14 |
15 | (defn- build-counter [counter-key]
16 | (fx/expanded
17 | (fx/column
18 | {:mainAxisAlignment MainAxisAlignment/center}
19 | {:name :ctr-col
20 | ;; The column maintains its own state, aka "in-place state".
21 | ;; We find it useful to give every widget a "value" property for holding the primary value of a widget
22 | :value (cI 0)}
23 | (fx/text (str/capitalize (name counter-key)))
24 | (fx/text {:style (fx/within-ctx [me ctx]
25 | (-> (Theme/of ctx) .-textTheme .-displayLarge))}
26 | (str (mx/muv :ctr-col)))
27 | (fx/elevated-button
28 | {:onPressed (fn ^void []
29 | (mx/mswap! (mx/fm* :ctr-col) :value inc))}
30 | (fx/text "+")))))
31 |
32 | (defn make-app []
33 | (fx/material-app {:title "Two Counters (MX)"
34 | :theme (cF (ThemeData .primarySwatch Colors/blue))}
35 | (fx/scaffold
36 | {:appBar (AppBar .title (Text "Two Counters (MX)"))}
37 | (fx/center
38 | (fx/row
39 | {:mainAxisAlignment MainAxisAlignment/center}
40 | (mapv #(build-counter %)
41 | [:left :right]))))))
--------------------------------------------------------------------------------
/examples/example/eg/x040_named_routes.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x040-named-routes
2 | "Port of CLJD sample.navigate-named-routes...
3 | Port of https://docs.flutter.dev/cookbook/navigation/named-routes.html"
4 | (:require
5 | [tilton.fmx.api :as fx
6 | :refer [dart-cb scaffold app-bar elevated-button text center material-app ]]
7 | ["package:flutter/material.dart" :as m]))
8 |
9 | ;; KNOWN BUG: Coming into this example on hot reload after a different example was running
10 | ;; fails in builder on "Null check operator used on a null value"
11 |
12 | (defn first-screen [ctx]
13 | (scaffold
14 | {:appBar (app-bar
15 | {:title (m/Text "First Screen")})}
16 | (center
17 | (elevated-button
18 | {:onPressed (dart-cb []
19 | (.pushNamed (-> ctx m/Navigator.of) "/second"))}
20 | (text "Launch Screen")))))
21 |
22 | (defn second-screen [ctx]
23 | (scaffold
24 | {:appBar (app-bar
25 | {:title (m/Text "Second Screen")})}
26 | (center
27 | (elevated-button
28 | {:onPressed (dart-cb []
29 | (-> ctx m/Navigator.of .pop))}
30 | (fx/text "Go Back!")))))
31 |
32 | (defn make-app []
33 | (material-app
34 | {:title "Navigation Basics"
35 | :initialRoute "/"
36 | :routes (into {}
37 | (for [[k gen] {"/" first-screen
38 | "/second" second-screen}]
39 | [k (fn ^m/Widget k [ctx]
40 | (fx/fx-render ctx
41 | (gen ctx)))]))}))
--------------------------------------------------------------------------------
/examples/example/eg/x04_drawer.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x04-drawer
2 | (:require
3 | [tilton.mx.cell.core :refer [cF cF+ cF_ cI c_F]]
4 | ["package:flutter/widgets.dart" :as w]
5 | ["package:flutter/material.dart" :as m]
6 | ["package:flutter/painting.dart" :as p]
7 | [tilton.fmx.api :as fx]
8 | [tilton.mx.base :refer [dprn dp dpx]]))
9 |
10 | (defn make-app []
11 | (fx/material-app
12 | {:title "Drawer Demo"}
13 | (fx/scaffold
14 | {:appBar (fx/app-bar
15 | {:title (m/Text "Drawer Demo")})
16 | :drawer (cF (fx/drawer
17 | (fx/list-view
18 | {:padding m/EdgeInsets.zero}
19 | (fx/drawer-header
20 | {:decoration (m/BoxDecoration .color m/Colors.blue)}
21 | (m/Text "Drawer Header 2"))
22 | ;; below, two diff ways of getting a builder wrapper, for the right context
23 | (fx/list-tile
24 | {:title (m/Text "Item 1")
25 | :onTap (fx/within-ctx [me ctx]
26 | #(.pop (m/Navigator.of ctx)))}
27 | {:with-builder? true})
28 | (fx/builder
29 | (fx/list-tile
30 | {:title (m/Text "Item 2")
31 | :onTap (fx/within-ctx [me ctx]
32 | #(.pop (m/Navigator.of ctx)))})))))}
33 | (fx/center
34 | (fx/text "My Ported Page!!")))))
35 |
36 |
37 |
--------------------------------------------------------------------------------
/examples/example/eg/x066_autocomplete_object.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x066-autocomplete-object
2 | "F/mx port of https://api.flutter.dev/flutter/material/Autocomplete-class.html"
3 | (:require
4 | [clojure.string :as str]
5 | [tilton.mx.api :refer [dp mget mset! mswap!] :as md]
6 | [tilton.fmx.api :as fx]
7 | [tilton.fmx.factory :as fxf]
8 | ["package:flutter/widgets.dart" :as w]
9 | ["package:flutter/material.dart" :as m]
10 | ["package:flutter/painting.dart" :as p]))
11 |
12 | ;;; --- autocomplete with object ----------------------------
13 |
14 | (def users [{:name "Alice" :email "alice@example.com"}
15 | {:name "Bob" :email "bob@example.com"}
16 | {:name "Charlie" :email "charlie123@gmail.com"}])
17 |
18 | (defn autocomplete-custom-type []
19 | (#/(m/Autocomplete Map)
20 | .onSelected (fn [sel] (prn :selection!! sel))
21 | .displayStringForOption (fn [{:keys [name email] :as opt}]
22 | (str name ": " email))
23 | .optionsBuilder (fn [^m/TextEditingValue val]
24 | (cond
25 | (= "" (.-text val))
26 | (.empty #/(Iterable Map))
27 | ;--
28 | :else
29 | (let [^#/(Iterable Map) it
30 | (.where ^List users
31 | (fn [option]
32 | (dp :jwoption option)
33 | (boolean
34 | (when (str/includes? (str option)
35 | (str/lower-case (.-text val)))
36 | option))))]
37 | it)))))
38 |
39 | (defn make-app []
40 | (let [title "Autocomplete Basic"]
41 | (fx/material-app {:title title}
42 | (fx/scaffold
43 | {:appBar (m/AppBar .title (m/Text title))}
44 | (fx/center
45 | (fx/column {:mainAxisAlignment m/MainAxisAlignment.center}
46 | (fx/text (str "Type below one of " (str/join "," users) "."))
47 | (autocomplete-custom-type)))))))
--------------------------------------------------------------------------------
/examples/example/eg/x06_tabs.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x06-tabs
2 | (:require
3 | [tilton.fmx.api :as fx]
4 | ["package:flutter/material.dart" :as m]))
5 |
6 | ;; partial port of CLJD tabs sample, incidentally demonstrating
7 | ;; that non-MX components can be added to MX components
8 |
9 | (defn make-app
10 | []
11 | (let [title "Tabs Demo"]
12 | (fx/material-app {:title title}
13 | (fx/default-tab-controller
14 | {:length 3}
15 | (fx/scaffold
16 | {:appBar (fx/app-bar
17 | {:bottom (m/TabBar
18 | .tabs [(m/Tab .icon (m/Icon m/Icons.directions_car)),
19 | (m/Tab .icon (m/Icon m/Icons.directions_transit)),
20 | (m/Tab .icon (m/Icon m/Icons.directions_bike))])})}
21 | (m/TabBarView
22 | .children [(m/Tab .icon (m/Icon. m/Icons.directions_car)),
23 | (m/Tab .icon (m/Icon. m/Icons.directions_transit)),
24 | (m/Tab .icon (m/Icon. m/Icons.directions_bike))]))))))
--------------------------------------------------------------------------------
/examples/example/eg/x07_animated_container.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x07-animated-container
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | [tilton.mx.api :refer [dp dpx wmx-iso minfo mget mset! mupdate! mav muv fm* cF cF+ cI]]
5 | [tilton.fmx.api :as fx]))
6 |
7 | (defn random-to-double [max]
8 | (-> max rand-int .toDouble))
9 |
10 | (defn random-color []
11 | (m/Color.fromRGBO (rand-int 256)
12 | (rand-int 256)
13 | (rand-int 256)
14 | 1))
15 |
16 | (defn make-app []
17 | (fx/material-app
18 | (fx/scaffold
19 | {:appBar (fx/app-bar {:title (fx/text "Animated Container Demo")})
20 | :floatingActionButton
21 | (cF (fx/floating-action-button
22 | {:onPressed (fx/dart-cb []
23 | (let [anicon (fm* :anicon)]
24 | (mupdate! anicon :config assoc
25 | :width (random-to-double 300)
26 | :height (random-to-double 300)
27 | :color (random-color)
28 | :borderRadius (m/BorderRadius.circular (random-to-double 100)))))}
29 | (fx/icon m/Icons.play_arrow)))}
30 |
31 | (fx/center
32 | (fx/animated-container
33 | {:width (cF (:width (mav :config)))
34 | :height (cF (:height (mav :config)))
35 | :decoration (cF (let [config (mav :config)]
36 | (m/BoxDecoration
37 | .color (:color config)
38 | .borderRadius (:borderRadius config))))
39 | :duration (Duration .seconds 1)
40 | :curve m/Curves.fastOutSlowIn}
41 | {:name :anicon
42 | :config (cI {:width 50.0
43 | :height 50.0
44 | :color m/Colors.green
45 | :borderRadius (m/BorderRadius.circular 8.0)})})))))
--------------------------------------------------------------------------------
/examples/example/eg/x08_navigation.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x08-navigation
2 | "Port of CLJD port of https://docs.flutter.dev/cookbook/navigation/navigation-basics"
3 | (:require
4 | ["package:flutter/material.dart" :as m]
5 | [tilton.mx.api :as mx :refer [dp]]
6 | [tilton.fmx.api :as fx
7 | :refer [within-ctx ctx-page-pop fx-render app-bar center scaffold
8 | elevated-button text builder material-app]]))
9 |
10 | (defn second-route []
11 | (scaffold
12 | {:appBar (app-bar {:title (text "Second Route")})}
13 | (center
14 | (elevated-button
15 | {:onPressed (within-ctx [me ctx]
16 | #(ctx-page-pop ctx))}
17 | (m/Text "Go back!")))))
18 |
19 | (defn my-ctx-page-push [ctx fx-page-def]
20 | (.push (-> ctx m/Navigator.of)
21 | (#/(m/MaterialPageRoute Object)
22 | .settings (m/RouteSettings .name "/second")
23 | .builder (fn [builder-ctx]
24 | (fx-render builder-ctx fx-page-def)))))
25 |
26 | (defn make-app []
27 | (material-app
28 | {:title "Navigation Basics"}
29 | (scaffold
30 | {:appBar (app-bar {:title (text "First Route")})}
31 | (center
32 | (builder ;; makes Navigator visible to .of
33 | (elevated-button
34 | {:onPressed (within-ctx [me ctx]
35 | #(my-ctx-page-push ctx (second-route)))}
36 | ;;{:with-builder? true} ;; alternate way of wrapping with fresh ctx
37 | (text "Open route")))))))
--------------------------------------------------------------------------------
/examples/example/eg/x09_form_change.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x09-form-change
2 | (:require
3 | [tilton.mx.api :refer [dp dpx wmx-iso minfo mget mset! mupdate! mav muv
4 | fasc fm* cF cF+ cI cFonce ]]
5 | [tilton.fmx.api :refer [dart-cb] :as fx]
6 | ["package:flutter/widgets.dart"
7 | :refer [Text State StatefulWidget StatelessWidget] :as w]
8 | ["package:flutter/material.dart" :as m
9 | :refer [MainAxisAlignment Colors Theme Icon Icons ThemeData runApp AppBar State]]
10 | ["package:flutter/painting.dart"
11 | :refer [TextStyle]]))
12 |
13 | (defn make-app []
14 | (let [title "Text field change detection"]
15 | (fx/material-app {:title title}
16 | (fx/scaffold
17 | {:appBar (fx/app-bar {:title (m/Text title)})}
18 | (fx/padding
19 | {:padding (m/EdgeInsets.all 16.0)}
20 | (fx/column
21 | {:mainAxisAlignment MainAxisAlignment/center}
22 | (fx/text-field
23 | {:onChanged (dart-cb [text]
24 | (mset! me :value text))}
25 | {:name :input-a
26 | :value (cI nil :watch (fn [prop me newv priorv c]
27 | (dp (str "First text field: " newv))))})
28 | (fx/text-field
29 | {:onChanged (dart-cb [text]
30 | (mset! me :value text))}
31 | {:name :input-b
32 | :value (cI "And then...?")
33 | :controller (cFonce (let [c (m/TextEditingController .text (mget me :value))]
34 | (.addListener c
35 | (fn [] (dp (str "Second text field: " (.-text c)))))
36 | c))})
37 | (fx/text (str "(a) " (muv :input-a) " and (b) " (muv :input-b)))))))))
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/examples/example/eg/x09_form_input.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x09-form-input
2 | "Port of CLJD faithful port of https://docs.flutter.dev/cookbook/forms/retrieve-input"
3 | (:require
4 | [tilton.mx.api :refer [dp mget mset! mswap!] :as md]
5 | [tilton.fmx.api :as fx]
6 | [tilton.fmx.factory :as fxf]
7 | ["package:flutter/widgets.dart" :as w]
8 | ["package:flutter/material.dart" :as m]
9 | ["package:flutter/painting.dart" :as p]))
10 |
11 | (defn make-app []
12 | (let [title "Retrieve text input 2"]
13 | (fx/material-app {:title title}
14 | (fx/scaffold
15 | {:appBar (m/AppBar .title (m/Text title))
16 | :floatingActionButton
17 | (fx/floating-action-button
18 | {:onPressed (fx/within-ctx [me ctx]
19 | #(m/showDialog
20 | .context ctx
21 | .builder (fn [ctx]
22 | (fxf/binding-ctx :show-dlg ctx
23 | (m/AlertDialog
24 | .content (m/Text (.-text ^m/TextEditingController
25 | (md/mget (md/fm* :test-input) :controller))))))))
26 | :tooltip "Show me the value!"}
27 | {:with-builder? true}
28 | (m/Icon m/Icons.text_fields))}
29 | (fx/column {:mainAxisAlignment m/MainAxisAlignment.center}
30 | (fx/text "Enter some text, then hit the FAB!")
31 | (fx/padding
32 | {:padding (m/EdgeInsets.all 16.0)}
33 | (fx/text-field {:controller (m/TextEditingController)}
34 | {:name :test-input})))))))
35 |
36 |
--------------------------------------------------------------------------------
/examples/example/eg/x10_datatable.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x10-datatable
2 | (:require
3 | [tilton.fmx.api :as fx]
4 | ["package:flutter/material.dart" :as m]))
5 |
6 | (defn data-table [& {:keys [cols rows]}]
7 | (fx/single-child-scroll-view
8 | {:scrollDirection m/Axis.vertical}
9 | (fx/data-table
10 | {:headingTextStyle (m/TextStyle
11 | .fontWeight m/FontWeight.bold
12 | .color m/Colors.blue)
13 | :showBottomBorder true
14 | :columns (map (fn [col]
15 | (m/DataColumn .label (m/Text col))) cols)
16 | :rows (map (fn [row]
17 | (m/DataRow .cells (mapv (fn [cell] (m/DataCell (m/Text cell)))
18 | row))) rows)})))
19 |
20 | (defn make-app []
21 | (fx/material-app {:debugShowCheckedModeBanner false}
22 | (fx/scaffold {:appBar (fx/app-bar {:title (fx/text (str "DataTable Sample"))})}
23 | (fx/center
24 | (data-table :cols ["#" "Name" "Age" "City"]
25 | :rows [["1" "zm" "42" "guangzhou"]
26 | ["2" "zrj" "10" "guangzhou"]
27 | ["3" "wrp" "13" "hongkong"]
28 | ["4" "wrl" "11" "guangzhou"]
29 | ["1" "zm" "42" "guangzhou"]
30 | ["2" "zrj" "10" "guangzhou"]
31 | ["3" "wrp" "13" "hongkong"]
32 | ["4" "wrl" "11" "guangzhou"]
33 | ["1" "zm" "42" "guangzhou"]
34 | ["2" "zrj" "10" "guangzhou"]
35 | ["3" "wrp" "13" "hongkong"]
36 | ["4" "wrl" "11" "guangzhou"]
37 | ["1" "zm" "42" "guangzhou"]
38 | ["2" "zrj" "10" "guangzhou"]
39 | ["3" "wrp" "13" "hongkong"]
40 | ["4" "wrl" "11" "guangzhou"]
41 | ["1" "zm" "42" "guangzhou"]
42 | ["2" "zrj" "10" "guangzhou"]
43 | ["3" "wrp" "13" "hongkong"]
44 | ["4" "wrl" "11" "guangzhou"]
45 | ["1" "zm" "42" "guangzhou"]
46 | ["2" "zrj" "10" "guangzhou"]
47 | ["3" "wrp" "13" "hongkong"]
48 | ["4" "wrl" "11" "guangzhou"]
49 | ["1" "zm" "42" "guangzhou"]
50 | ["2" "zrj" "10" "guangzhou"]
51 | ["3" "wrp" "13" "hongkong"]
52 | ["4" "wrl" "11" "guangzhou"]
53 | ["5" "wrj" "10" "beijing"]])))))
--------------------------------------------------------------------------------
/examples/example/eg/x11_grid_list.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x11-grid-list
2 | "MX Port of CLJD faithful port of https://docs.flutter.dev/cookbook/lists/grid-lists"
3 | (:require
4 | [tilton.fmx.api :as fx]
5 | ["package:flutter/widgets.dart" :as w]
6 | ["package:flutter/material.dart" :as m]))
7 |
8 | (defn make-app []
9 | (let [title "Grid List"]
10 | (fx/material-app {:title title}
11 | (fx/scaffold {:appBar (fx/app-bar {:title (m/Text "A Grid List Example")})}
12 | ; --- implicit body ---
13 | (fx/builder
14 | (fx/grid-view+count
15 | {:crossAxisCount 2}
16 | (mapv
17 | (fn [i] (fx/center
18 | (fx/text
19 | {:style (fx/within-ctx [me ctx]
20 | (-> (m/Theme.of ctx) .-textTheme .-displaySmall))}
21 | (str "Item " i))))
22 | (range 100))))))))
--------------------------------------------------------------------------------
/examples/example/eg/x13_snackbar.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x13-snackbar
2 | "Flummox port of CLJD Faithful port of https://docs.flutter.dev/cookbook/design/snackbars"
3 | (:require
4 | ["package:flutter/material.dart" :as m]
5 | [tilton.mx.base :refer [dprn dp dpx]]
6 | [tilton.mx.api :refer [cI cF cFn cF+ minfo] :as mx]
7 | [tilton.fmx.factory :as fxf]
8 | [tilton.fmx.api :as fx
9 | :refer [snack-bar material-app scaffold center elevated-button text app-bar fx-render dart-cb]]))
10 |
11 | ;; Original: https://github.com/Tensegritics/ClojureDart/tree/main/samples/snackbar
12 | ;; ^^^ Copyright 2022 by Tensegritics, Eclipse
13 |
14 | (defn make-app []
15 | (let [title "Snackbar Demo"]
16 | (material-app
17 | {:title title}
18 | (scaffold
19 | {:appBar (app-bar {:title (text title)})}
20 | (center
21 | (fx/builder
22 | (elevated-button
23 | {:onPressed (dart-cb []
24 | (.showSnackBar (m/ScaffoldMessenger.of ctx)
25 | (fx-render ctx
26 | (snack-bar {:action (m/SnackBarAction
27 | .label "Undo!"
28 | .onPressed (fn [] (dart:core/print :UNDO!!!!!)))
29 | :content (text "Yay! A SnackBar!")}))))}
30 | ;; {:with-builder? true} ;; <============== option 2
31 | (text "Show text"))))))))
32 |
33 |
--------------------------------------------------------------------------------
/examples/example/eg/x14_hero.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x14-hero
2 | "FlutterMX port of CLJD Faithful port of https://docs.flutter.dev/cookbook/navigation/hero-animations"
3 | (:require ["package:flutter/material.dart" :as m]
4 | [tilton.fmx.api :refer [dart-cb] :as fx]))
5 |
6 | (def detail-screen
7 | (fx/scaffold
8 | (fx/gesture-detector
9 | {:onTap (dart-cb []
10 | (.pop (m/Navigator.of ctx)))}
11 | (fx/center
12 | (fx/hero {:tag "imageHero"}
13 | (m/Image .image (m/AssetImage "image/einstein.jpeg")))))))
14 |
15 | (defn make-app []
16 | (let []
17 | (fx/material-app
18 | {:debugShowCheckedModeBanner false}
19 | (fx/scaffold
20 | {:appBar (fx/app-bar {:title (fx/text "Main Screen")})}
21 | (fx/builder
22 | (fx/gesture-detector
23 | {:onTap (dart-cb []
24 | (.push (m/Navigator.of ctx)
25 | (#/(m/MaterialPageRoute Object)
26 | .builder (fn [ctx]
27 | (fx/fx-render ctx
28 | detail-screen)))))}
29 | (fx/hero {:tag "imageHero"}
30 | ;; required a pubspec.yaml "assets:" entry and add a path to a JPEG,
31 | (m/Image .image (m/AssetImage "image/john.jpeg")))))))))
32 |
--------------------------------------------------------------------------------
/examples/example/eg/x15_fade_widget.cljd:
--------------------------------------------------------------------------------
1 | (ns example.eg.x15-fade-widget
2 | "FlutterMX port of CLJD Faithful port of https://docs.flutter.dev/cookbook/animation/opacity-animation"
3 | (:require ["package:flutter/material.dart" :as m]
4 | [tilton.mx.api :refer [dp dpx wmx-iso minfo mget mset! mupdate! muv fm* cF cI]]
5 | [tilton.fmx.api :as fx]))
6 |
7 | (defn make-app []
8 | (let [title "Opacity Demo"]
9 | (fx/material-app
10 | {:title title
11 | :debugShowCheckedModeBanner false}
12 | {:name :zapp}
13 | (fx/scaffold
14 | {:appBar (fx/app-bar {:title (fx/text title)})
15 | :floatingActionButton (fx/within-ctx [me ctx]
16 | (fx/floating-action-button
17 | {:tooltip "Toggle Opacity"
18 | :onPressed #(wmx-iso (mupdate! me :visible not))}
19 | (fx/icon m/Icons.flip)))}
20 | {:visible (cI true)
21 | :name :my-home}
22 | (fx/center {}
23 | {:name :zcenter}
24 | (fx/animated-opacity
25 | {:opacity (cF (cond (true? (mget (fm* :my-home) :visible)) 1.0
26 | :else 0.0))
27 | :duration (Duration .milliseconds 500)}
28 | {:name :ani-opa}
29 | (m/Container .width 200.0 .height 200.0 .color m/Colors.teal)))))))
--------------------------------------------------------------------------------
/examples/example/non_fmx/ctx_row.cljd:
--------------------------------------------------------------------------------
1 | (ns example.non-fmx.ctx-row
2 | (:require
3 | ["package:flutter/cupertino.dart" :as cupertinoIcons]
4 | ["package:flutter/material.dart" :as m]
5 | ["package:flutter/widgets.dart" :as w]
6 | [cljd.flutter :as f]
7 | [tilton.fmx.factory :as fxf]
8 | [tilton.mx.api :as mx
9 | :refer [dp dpx cI cF cF+ cF+n cFn cFonce mget mget? mset! mswap! minfo fasc fasc-inc
10 | fmu muv fm* mav mx-bound? wmx-iso with-cc mmx-md cFkids]]
11 | [tilton.fmx.api :as fx
12 | :refer [scaffold app-bar text center column hero material-app visibility
13 | container row expanded icon padding opacity ignore-pointer
14 | checkbox-list-tile icon-button fx-render dart-cb
15 | text-field selection-area safe-area sized-box elevated-button]]))
16 |
17 | ;;; Demonstrating conditional structure decided off context
18 |
19 | (defn get-width [ctx] (.-width (.-size (m/MediaQuery.of ctx))))
20 |
21 | (defn make-app []
22 | (material-app
23 | {:title "F/MX Chat Arena"
24 | :theme (m/ThemeData .useMaterial3 true)}
25 | (scaffold
26 | {:appBar (app-bar {:title (text "F/MX Chat Arena")})}
27 | (center ;; {} {:dummy (cI 42)}
28 | (row {:mainAxisAlignment m/MainAxisAlignment.spaceEvenly}
29 | (when (> (get-width fxf/*ctx*) 600)
30 | (text "Hide If Not Wide"))
31 | (text "Always 1")
32 | (text "Always 2"))))))
33 |
34 |
--------------------------------------------------------------------------------
/fonts/Inter-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/fonts/Inter-Regular.ttf
--------------------------------------------------------------------------------
/fonts/RobotoMono-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/fonts/RobotoMono-Light.ttf
--------------------------------------------------------------------------------
/fonts/RobotoMono-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/fonts/RobotoMono-Thin.ttf
--------------------------------------------------------------------------------
/goopi.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | clj -M:cljd flutter --dart-define=GOOG_AI_API_KEY=$GOOG_AI_API_KEY
4 |
--------------------------------------------------------------------------------
/image/800px-Depth-first-tree.svg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/800px-Depth-first-tree.svg.png
--------------------------------------------------------------------------------
/image/Depth-First-Search.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/Depth-First-Search.gif
--------------------------------------------------------------------------------
/image/HW d Sim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/HW d Sim.png
--------------------------------------------------------------------------------
/image/HW d all.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/HW d all.png
--------------------------------------------------------------------------------
/image/HW d chrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/HW d chrome.png
--------------------------------------------------------------------------------
/image/HW d macos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/HW d macos.png
--------------------------------------------------------------------------------
/image/cat_on_snow.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/cat_on_snow.jpeg
--------------------------------------------------------------------------------
/image/counter-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/counter-app.png
--------------------------------------------------------------------------------
/image/earth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/earth.png
--------------------------------------------------------------------------------
/image/einstein.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/einstein.jpeg
--------------------------------------------------------------------------------
/image/game-over.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/game-over.png
--------------------------------------------------------------------------------
/image/hello-world-app.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/hello-world-app.jpg
--------------------------------------------------------------------------------
/image/jmccarthy.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/jmccarthy.jpeg
--------------------------------------------------------------------------------
/image/john.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/john.jpeg
--------------------------------------------------------------------------------
/image/kenny-naut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/kenny-naut.png
--------------------------------------------------------------------------------
/image/kernighan.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/kernighan.jpeg
--------------------------------------------------------------------------------
/image/lake-oeschinen.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/lake-oeschinen.jpeg
--------------------------------------------------------------------------------
/image/scone.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/scone.jpeg
--------------------------------------------------------------------------------
/image/todomvc-app.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/todomvc-app.jpeg
--------------------------------------------------------------------------------
/image/trophy.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/trophy.jpeg
--------------------------------------------------------------------------------
/image/under-construction.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/image/under-construction.jpeg
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 12.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, '12.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | target 'RunnerTests' do
36 | inherit! :search_paths
37 | end
38 | end
39 |
40 | post_install do |installer|
41 | installer.pods_project.targets.each do |target|
42 | flutter_additional_ios_build_settings(target)
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - app_links (0.0.2):
3 | - Flutter
4 | - audio_session (0.0.1):
5 | - Flutter
6 | - Flutter (1.0.0)
7 | - flutter_sound (9.19.1):
8 | - Flutter
9 | - flutter_sound_core (= 9.19.1)
10 | - flutter_sound_core (9.19.1)
11 | - flutter_tts (0.0.1):
12 | - Flutter
13 | - just_audio (0.0.1):
14 | - Flutter
15 | - path_provider_foundation (0.0.1):
16 | - Flutter
17 | - FlutterMacOS
18 | - shared_preferences_foundation (0.0.1):
19 | - Flutter
20 | - FlutterMacOS
21 | - speech_to_text (0.0.1):
22 | - Flutter
23 | - FlutterMacOS
24 | - Try
25 | - Try (2.1.1)
26 | - url_launcher_ios (0.0.1):
27 | - Flutter
28 |
29 | DEPENDENCIES:
30 | - app_links (from `.symlinks/plugins/app_links/ios`)
31 | - audio_session (from `.symlinks/plugins/audio_session/ios`)
32 | - Flutter (from `Flutter`)
33 | - flutter_sound (from `.symlinks/plugins/flutter_sound/ios`)
34 | - flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
35 | - just_audio (from `.symlinks/plugins/just_audio/ios`)
36 | - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
37 | - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
38 | - speech_to_text (from `.symlinks/plugins/speech_to_text/darwin`)
39 | - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
40 |
41 | SPEC REPOS:
42 | trunk:
43 | - flutter_sound_core
44 | - Try
45 |
46 | EXTERNAL SOURCES:
47 | app_links:
48 | :path: ".symlinks/plugins/app_links/ios"
49 | audio_session:
50 | :path: ".symlinks/plugins/audio_session/ios"
51 | Flutter:
52 | :path: Flutter
53 | flutter_sound:
54 | :path: ".symlinks/plugins/flutter_sound/ios"
55 | flutter_tts:
56 | :path: ".symlinks/plugins/flutter_tts/ios"
57 | just_audio:
58 | :path: ".symlinks/plugins/just_audio/ios"
59 | path_provider_foundation:
60 | :path: ".symlinks/plugins/path_provider_foundation/darwin"
61 | shared_preferences_foundation:
62 | :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
63 | speech_to_text:
64 | :path: ".symlinks/plugins/speech_to_text/darwin"
65 | url_launcher_ios:
66 | :path: ".symlinks/plugins/url_launcher_ios/ios"
67 |
68 | SPEC CHECKSUMS:
69 | app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0
70 | audio_session: 088d2483ebd1dc43f51d253d4a1c517d9a2e7207
71 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
72 | flutter_sound: 106279b6d138116ad5fe619a967a518a81bb29ee
73 | flutter_sound_core: 456fad87eeaa78cf33dca80c4a7c087487745cec
74 | flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
75 | just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
76 | path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
77 | shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
78 | speech_to_text: 627d3fd2194770b51abb324ba45c2d39398f24a8
79 | Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96
80 | url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
81 |
82 | PODFILE CHECKSUM: 7be2f5f74864d463a8ad433546ed1de7e0f29aef
83 |
84 | COCOAPODS: 1.16.2
85 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @main
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSMicrophoneUsageDescription
6 | This app uses the microphone to capture and recognize voice commands.
7 | NSSpeechRecognitionUsageDescription
8 | This app uses speech recognition to get commands from user voice
9 | NSAppTransportSecurity
10 |
11 | NSAllowsArbitraryLoads
12 |
13 |
14 | io.flutter.embedded_views_preview
15 |
16 | CFBundleDevelopmentRegion
17 | $(DEVELOPMENT_LANGUAGE)
18 | CFBundleDisplayName
19 | Cljd Flutter Mx
20 | CFBundleExecutable
21 | $(EXECUTABLE_NAME)
22 | CFBundleIdentifier
23 | $(PRODUCT_BUNDLE_IDENTIFIER)
24 | CFBundleInfoDictionaryVersion
25 | 6.0
26 | CFBundleName
27 | cljd_flutter_mx
28 | CFBundlePackageType
29 | APPL
30 | CFBundleShortVersionString
31 | $(FLUTTER_BUILD_NAME)
32 | CFBundleSignature
33 | ????
34 | CFBundleVersion
35 | $(FLUTTER_BUILD_NUMBER)
36 | LSRequiresIPhoneOS
37 |
38 | UILaunchStoryboardName
39 | LaunchScreen
40 | UIMainStoryboardFile
41 | Main
42 | UISupportedInterfaceOrientations
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 | UISupportedInterfaceOrientations~ipad
49 |
50 | UIInterfaceOrientationPortrait
51 | UIInterfaceOrientationPortraitUpsideDown
52 | UIInterfaceOrientationLandscapeLeft
53 | UIInterfaceOrientationLandscapeRight
54 |
55 | UIViewControllerBasedStatusBarAppearance
56 |
57 | CADisableMinimumFrameDurationOnPhone
58 |
59 | UIApplicationSupportsIndirectInputEvents
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | export "cljd-out/tilton/main.dart" show main;
2 |
--------------------------------------------------------------------------------
/macos/.gitignore:
--------------------------------------------------------------------------------
1 | # Flutter-related
2 | **/Flutter/ephemeral/
3 | **/Pods/
4 |
5 | # Xcode-related
6 | **/dgph
7 | **/xcuserdata/
8 |
--------------------------------------------------------------------------------
/macos/Flutter/Flutter-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Flutter/Flutter-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Flutter/GeneratedPluginRegistrant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | import FlutterMacOS
6 | import Foundation
7 |
8 | import app_links
9 | import audio_session
10 | import flutter_tts
11 | import just_audio
12 | import path_provider_foundation
13 | import shared_preferences_foundation
14 | import speech_to_text
15 | import url_launcher_macos
16 |
17 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
18 | AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
19 | AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
20 | FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin"))
21 | JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
22 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
23 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
24 | SpeechToTextPlugin.register(with: registry.registrar(forPlugin: "SpeechToTextPlugin"))
25 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
26 | }
27 |
--------------------------------------------------------------------------------
/macos/Podfile:
--------------------------------------------------------------------------------
1 | platform :osx, '10.15'
2 |
3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
5 |
6 | project 'Runner', {
7 | 'Debug' => :debug,
8 | 'Profile' => :release,
9 | 'Release' => :release,
10 | }
11 |
12 | def flutter_root
13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
14 | unless File.exist?(generated_xcode_build_settings_path)
15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
16 | end
17 |
18 | File.foreach(generated_xcode_build_settings_path) do |line|
19 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
20 | return matches[1].strip if matches
21 | end
22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
23 | end
24 |
25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
26 |
27 | flutter_macos_podfile_setup
28 |
29 | target 'Runner' do
30 | use_frameworks!
31 | use_modular_headers!
32 |
33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
34 | target 'RunnerTests' do
35 | inherit! :search_paths
36 | end
37 | end
38 |
39 | post_install do |installer|
40 | installer.pods_project.targets.each do |target|
41 | flutter_additional_macos_build_settings(target)
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/macos/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - app_links (1.0.0):
3 | - FlutterMacOS
4 | - audio_session (0.0.1):
5 | - FlutterMacOS
6 | - flutter_tts (0.0.1):
7 | - FlutterMacOS
8 | - FlutterMacOS (1.0.0)
9 | - just_audio (0.0.1):
10 | - FlutterMacOS
11 | - path_provider_foundation (0.0.1):
12 | - Flutter
13 | - FlutterMacOS
14 | - shared_preferences_foundation (0.0.1):
15 | - Flutter
16 | - FlutterMacOS
17 | - speech_to_text (0.0.1):
18 | - Flutter
19 | - FlutterMacOS
20 | - Try
21 | - Try (2.1.1)
22 | - url_launcher_macos (0.0.1):
23 | - FlutterMacOS
24 |
25 | DEPENDENCIES:
26 | - app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`)
27 | - audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`)
28 | - flutter_tts (from `Flutter/ephemeral/.symlinks/plugins/flutter_tts/macos`)
29 | - FlutterMacOS (from `Flutter/ephemeral`)
30 | - just_audio (from `Flutter/ephemeral/.symlinks/plugins/just_audio/macos`)
31 | - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
32 | - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
33 | - speech_to_text (from `Flutter/ephemeral/.symlinks/plugins/speech_to_text/darwin`)
34 | - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
35 |
36 | SPEC REPOS:
37 | trunk:
38 | - Try
39 |
40 | EXTERNAL SOURCES:
41 | app_links:
42 | :path: Flutter/ephemeral/.symlinks/plugins/app_links/macos
43 | audio_session:
44 | :path: Flutter/ephemeral/.symlinks/plugins/audio_session/macos
45 | flutter_tts:
46 | :path: Flutter/ephemeral/.symlinks/plugins/flutter_tts/macos
47 | FlutterMacOS:
48 | :path: Flutter/ephemeral
49 | just_audio:
50 | :path: Flutter/ephemeral/.symlinks/plugins/just_audio/macos
51 | path_provider_foundation:
52 | :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
53 | shared_preferences_foundation:
54 | :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
55 | speech_to_text:
56 | :path: Flutter/ephemeral/.symlinks/plugins/speech_to_text/darwin
57 | url_launcher_macos:
58 | :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
59 |
60 | SPEC CHECKSUMS:
61 | app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a
62 | audio_session: dea1f41890dbf1718f04a56f1d6150fd50039b72
63 | flutter_tts: 64651204e5d276ffea5a910f942d5e9785a96085
64 | FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
65 | just_audio: 9b67ca7b97c61cfc9784ea23cd8cc55eb226d489
66 | path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
67 | shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
68 | speech_to_text: 627d3fd2194770b51abb324ba45c2d39398f24a8
69 | Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96
70 | url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
71 |
72 | PODFILE CHECKSUM: 9ebaf0ce3d369aaa26a9ea0e159195ed94724cf3
73 |
74 | COCOAPODS: 1.15.2
75 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | @main
5 | class AppDelegate: FlutterAppDelegate {
6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7 | return true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "app_icon_16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "app_icon_32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "app_icon_32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "app_icon_64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "app_icon_128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "app_icon_256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "app_icon_256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "app_icon_512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "app_icon_512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "app_icon_1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
--------------------------------------------------------------------------------
/macos/Runner/Configs/AppInfo.xcconfig:
--------------------------------------------------------------------------------
1 | // Application-level settings for the Runner target.
2 | //
3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4 | // future. If not, the values below would default to using the project name when this becomes a
5 | // 'flutter create' template.
6 |
7 | // The application's name. By default this is also the title of the Flutter window.
8 | PRODUCT_NAME = cljd_flutter_mx
9 |
10 | // The application's bundle identifier
11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.cljdFlutterMx
12 |
13 | // The copyright displayed in application information
14 | PRODUCT_COPYRIGHT = Copyright © 2023 com.example. All rights reserved.
15 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Debug.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Release.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2 | GCC_WARN_UNDECLARED_SELECTOR = YES
3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6 | CLANG_WARN_PRAGMA_PACK = YES
7 | CLANG_WARN_STRICT_PROTOTYPES = YES
8 | CLANG_WARN_COMMA = YES
9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES
10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12 | GCC_WARN_SHADOW = YES
13 | CLANG_WARN_UNREACHABLE_CODE = YES
14 |
--------------------------------------------------------------------------------
/macos/Runner/DebugProfile.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.assets.pictures.read-only
8 |
9 | com.apple.security.cs.allow-jit
10 |
11 | com.apple.security.files.downloads.read-only
12 |
13 | com.apple.security.network.server
14 |
15 | com.apple.security.network.client
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/macos/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | $(PRODUCT_COPYRIGHT)
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 |
32 |
33 |
--------------------------------------------------------------------------------
/macos/Runner/MainFlutterWindow.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | class MainFlutterWindow: NSWindow {
5 | override func awakeFromNib() {
6 | let flutterViewController = FlutterViewController()
7 | let windowFrame = self.frame
8 | self.contentViewController = flutterViewController
9 | self.setFrame(windowFrame, display: true)
10 |
11 | RegisterGeneratedPlugins(registry: flutterViewController)
12 |
13 | super.awakeFromNib()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/macos/Runner/Release.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.network.client
6 |
7 | com.apple.security.app-sandbox
8 |
9 | com.apple.security.assets.pictures.read-only
10 |
11 | com.apple.security.files.downloads.read-only
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/macos/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import FlutterMacOS
2 | import Cocoa
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/other/physics_sim_std.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.example.physics-sim-std
2 | "Faithful port of https://docs.flutter.dev/cookbook/animation/physics-simulation#interactive-example"
3 | (:require
4 | ["package:flutter/material.dart" :as m]
5 | ["package:flutter/physics.dart" :as p]
6 | [tilton.util.base :refer [dprn]]
7 | [cljd.flutter.alpha :as f]))
8 |
9 | ;; cgrand's notes: still a relative straight port, however I chose to differ from
10 | ;; the Dart code for the handling of the _animation field.
11 | ;; Dart code uses a single listener which has a ref to a late mutable field.
12 | ;; The invariants between the value of this field, the controller and
13 | ;; the gesture detector was implicit.
14 | ;; I preferred to create a new listener at each PanEnd which closes over the animation.
15 |
16 | (defn draggable-card [& {:keys [child]}]
17 | (f/widget
18 | :inherit [m/MediaQuery]
19 | :context ctx
20 | :ticker tick
21 | :with [controller (m/AnimationController :vsync tick)]
22 | :state [drag-alignment m.Alignment/center]
23 | (let [size (.size media-query)
24 | run-animation
25 | (fn [^m/Offset px-per-s]
26 | (let [animation (.drive controller
27 | (m/AlignmentTween
28 | :begin @drag-alignment
29 | :end m.Alignment/center))
30 | _ (dprn :boom-ani-std animation (dart/is? animation m/Animation))
31 | _ (dprn :early-ani-val!!!!!!!! (.value animation))
32 | units-per-s-x (/ (.dx px-per-s) (.width size))
33 | units-per-s-y (/ (.dy px-per-s) (.height size))
34 | units-per-s (m/Offset units-per-s-x units-per-s-y)
35 | unit-velocity (.distance units-per-s)
36 | spring ^:const (p/SpringDescription
37 | :mass 30
38 | :stiffness 1
39 | :damping 1)
40 | simulation (p/SpringSimulation spring 0 1 (- unit-velocity))]
41 | (doto controller
42 | .clearListeners
43 | (.addListener #(do
44 | ;(dprn :STD-ani animation)
45 | ;(dprn :STD-anival!!! (.value animation))
46 | (reset! drag-alignment (.value animation))))
47 | (.animateWith simulation))))]
48 | (f/nest
49 | (m/GestureDetector
50 | :onPanDown (fn [details] (.stop controller)
51 | nil)
52 | :onPanUpdate (fn [^m/DragUpdateDetails details]
53 | (dprn :updetails (/ (-> details .delta .dx) (/ (.width size) 2))
54 | (/ (-> details .delta .dy) (/ (.height size) 2)))
55 | (swap! drag-alignment
56 | #(.+ (m/Alignment
57 | (/ (-> details .delta .dx) (/ (.width size) 2))
58 | (/ (-> details .delta .dy) (/ (.height size) 2)))
59 | %))
60 | nil)
61 | :onPanEnd (fn [^m/DragEndDetails details]
62 | (run-animation (-> details .velocity .pixelsPerSecond))
63 | nil))
64 | (m/Align :alignment @drag-alignment)
65 | m/Card
66 | child))))
67 |
68 | (def physics-card-demo
69 | (f/widget
70 | (m/Scaffold
71 | :appBar (m/AppBar)
72 | :body (draggable-card :child (m/FlutterLogo :size 128)))))
73 |
74 | ;(defn main []
75 | ; (m/runApp (m/MaterialApp :home physics-card-demo)))
76 |
77 | (defn make-app []
78 | (m/MaterialApp :home physics-card-demo))
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | jar
5 | flutter-mx
6 | flutter-mx
7 | 0.1.0
8 | flutter-mx
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/tilton/fmx/material.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.fmx.material
2 | (:require
3 | ["dart:io" :as io]
4 | ["package:flutter/foundation.dart" :as foundation]
5 | ["package:flutter/material.dart" :as m]
6 | ["package:flutter/widgets.dart" :as w]
7 | ["package:flutter/painting.dart" :as p]
8 | [tilton.fmx.factory :refer [deftag] :as fxf]))
9 |
--------------------------------------------------------------------------------
/src/tilton/fmx/widgets.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.fmx.widgets
2 | (:require
3 | ["dart:io" :as io]
4 | ["package:flutter/foundation.dart" :as foundation]
5 | ["package:flutter/material.dart" :as m]
6 | ["package:flutter/widgets.dart" :as w]
7 | ["package:flutter/painting.dart" :as p]
8 | [tilton.fmx.factory :refer [deftag] :as fxf]))
9 |
--------------------------------------------------------------------------------
/src/tilton/main.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.main
2 | (:require
3 | ["package:flutter/material.dart" :as m]
4 | ["package:flutter/widgets.dart" :as w]
5 | ["package:flutter/foundation.dart" :as f]
6 | ["package:supabase_flutter/supabase_flutter.dart" :as supa]
7 | ["dart:io" :as io]
8 | ;[cljd.flutter :as f]
9 | [tilton.mx.cell.base :as cty]
10 | [tilton.mx.model.core :as md]
11 | [tilton.mx.util :as mxu]
12 | [tilton.mx.base
13 | :refer [wtrx dp dpx trx *fx$dpk*]]
14 | [tilton.mx.api :refer [navdbg minfo cinfo] :as mx]
15 | [tilton.fmx.factory :refer [fx$sst-registry-clear]]
16 | [tilton.fmx.api :as fx]
17 | [tilton.testing :as testing]
18 | [example.driver :as eg] ;; <--- comment out when excluding examples dir in deps.edn
19 | [example.eg.x01-counter :as excounter]
20 | [tilton.counter-app :as counter] ;; BROKEN. this one uses sugary defs for scaffold and material-app
21 | #_[learn.counter.counter-fmx :as l-ctr]))
22 |
23 | ;;; The main branch as-is excludes all but one example. To pull those in:
24 | ;;; * modify deps.edn to include "examples" in :paths;
25 | ;;; * uncomment [example.driver..] above;
26 | ;;; * uncomment (eg/select) below; and
27 | ;;; * restart the app to pick up the deps.edn.
28 |
29 | (defn main []
30 | (binding [#_#_ *async-error-handler* (fn [exc stack-trace]
31 | (dp :ASYNC-ERROR-TRAPS exc)
32 | (dp :ASYNC-ERROR-stack-trace stack-trace))
33 | *print-level* 5
34 | *print-length* 10
35 | *print-readably* true]
36 | (dp :main-entry--------------------------------------------)
37 |
38 |
39 | (fx/initialize)
40 |
41 | (binding [cty/*dpc-enabled* true]
42 | ; *fx$dpk* [:propagate :pulse :cset :cnset bbuild :bbuild+ :gg :sstate :sstate+]
43 | (.ensureInitialized w/WidgetsFlutterBinding)
44 |
45 | ; if using Supabase, activate this:
46 | #_ (do (dp :supa-URL (String/fromEnvironment "SUPA_MVX_URL"))
47 | (dp :supa-KEY (String/fromEnvironment "SUPA_MVX_KEY"))
48 | (dp :Supa-init
49 | (await (.initialize supa/Supabase
50 | .url (String/fromEnvironment "SUPA_MVX_URL")
51 | .anonKey (String/fromEnvironment "SUPA_MVX_KEY")))))
52 |
53 | (if false ;; as of 11/2024 we seem not to be able to run outside run-fx-app-hot
54 | (excounter/make-app)
55 | (fx/run-fx-app-hot
56 | (if false
57 | (excounter/make-app)
58 | (eg/select)))))
59 |
60 | #_(testing/run-tests)))
61 |
62 | #_(when (not (fx/is-web?))
63 | (dp :platform-processors io/Platform.numberOfProcessors))
64 |
65 | ;; (set! r/debugPaintSizeEnabled true)
66 | ;; (w/debugDumpApp)
67 |
68 | (defn sample-debugger [opcode data]
69 | (case opcode
70 | :mark-rebuild-unless-defunct
71 | (do) #_(let [{:keys [cell element]} data]
72 | (dp :adtata data)
73 | (dp :cell (cinfo cell))
74 | (dp :cellkeys (keys @cell))
75 | (let [elt ^w/Element element]
76 | (when (not (and (.-mounted elt)
77 | (.-debugIsActive elt)
78 | (not (.-debugIsDefunct elt))))
79 | (dp :rebld-DEAD-ELT-me!!! (minfo (:me @cell)))
80 | (dp :rebld-mounted (.-mounted elt))
81 | (dp :rebld-active (.-debugIsActive elt))
82 | (dp :rebld-sees-defunct (.-debugIsDefunct elt))
83 | (dp :rebld-elt-str (.toString elt)))))
84 | (dp :unrecognized-debug-opcode opcode data)))
--------------------------------------------------------------------------------
/src/tilton/mx/cell/observer.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.mx.cell.observer
2 | (:require
3 | [tilton.mx.foundation :refer [observe mx-type] :as mx]
4 | [tilton.mx.base
5 | :refer [trx dpx dp mx-throw]]
6 |
7 | [tilton.mx.util
8 | :refer [cl-find set-ify atom?
9 | make-fifo-queue fifo-empty? fifo-peek fifo-pop
10 | fifo-data fifo-add rmap-set!]
11 | :as ut]
12 |
13 | [tilton.mx.cell.base
14 | :refer [ unbound
15 | +pulse+ c-prop c-value c-mname
16 | c-model] :as cty]
17 |
18 | [tilton.mx.model.peek :refer [chk md-type mref? minfo cinfo cref?]]
19 |
20 | ["package:flutter/widgets.dart" :as w
21 | :refer [Text Center Expanded Column State StatefulWidget StatelessWidget]]))
22 |
23 | (def +observe-method+ (atom {}))
24 |
25 | (defn observer-register [key observer]
26 | (prn :watch-reg key)
27 | (swap! +observe-method+ assoc key observer))
28 |
29 | (def +observe-default-handler+ (atom nil))
30 |
31 | (defn observer-get [key]
32 | (get @+observe-method+ key))
33 |
34 | (defn fx-observe [prop-name me new-val old-val c]
35 | (chk me (str "model observe invoked for standalone cell? " (cinfo c)))
36 | (dpx :watch-oskool prop-name (minfo me) )
37 |
38 | (when-let [obs (:fx$observer @me)]
39 | ;; note that we carry on with generic observe after specific observe
40 | (do (dpx :oskool-using-obj-observer (minfo me))
41 | (obs prop-name me new-val old-val c)))
42 |
43 | (when-let [obs (observer-get (mx-type me))]
44 | (do (dpx :oskool-using-type-obs prop-name (mx-type me))
45 | (obs prop-name me new-val old-val c))))
46 |
47 | (defmacro fn-obs
48 | "Shortcut definer for cell-specific observers.
49 | body can be multiple sexprs with access to
50 | call parameters: prop, me, new, old, and c."
51 | [& body]
52 | `(fn [~'prop ~'me ~'new ~'old ~'c]
53 | ~@body))
54 |
55 | (defn c-observe
56 | ([c why]
57 | (c-observe c unbound why))
58 |
59 | ([c prior-value why]
60 | (chk (cref? c) (str "cref? fail on c-observe" (cinfo c)))
61 | (chk (dart/is? @+pulse+ int))
62 | (dpx :c-observe> why (cinfo c))
63 |
64 | (rmap-set! [:pulse-observed c] @+pulse+)
65 | (when-let [me (c-model c)] ;; not in standalone cells, mostly in test suite
66 | ;; we do observes specified for types or slots...
67 | (fx-observe (c-prop c) me (c-value c) prior-value c)
68 |
69 | (when-let [md-type (md-type (c-model c))]
70 | (mx/observe md-type (c-prop c) me (c-value c) prior-value c)))
71 |
72 | ;; ...and also do observes specified ad hoc on the cI/cF call.
73 | ;; nb that we do not want ad hoc observers to shadow those specified generically
74 | ;; indeed, in Lisp observers are progn methods -- they all run.
75 | (when-let [cell-observer (:obs @c)]
76 | (cell-observer (c-prop c) (c-model c) (c-value c) prior-value c))))
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/tilton/mx/cell/synapse.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.mx.cell.synapse
2 | (:require
3 | [tilton.mx.model.peek :refer [chk mref? minfo]]
4 | [tilton.mx.base :refer [dp]]
5 | [tilton.mx.util :refer [ pln rmap-set!]]
6 |
7 | [tilton.mx.cell.base
8 | :refer [*depender* c-synapses c-prop c-useds]]
9 |
10 | [tilton.mx.cell.integrity
11 | :refer [with-integrity]]
12 |
13 | [tilton.mx.cell.evaluate :refer [ cget c-value-assume
14 | record-dependency ensure-value-is-current]]
15 |
16 | [tilton.mx.cell.observer :refer [fn-obs]]
17 |
18 | [tilton.mx.cell.core
19 | :refer [cI make-c-formula c-fn]]))
20 |
21 | (defn existing-syn [synapse-id]
22 | (chk (keyword? synapse-id) "Synapse ID must be a keyword")
23 | (chk *depender* (str "You attempted to create synapse " synapse-id " outside a Cell formula. Synapses serve containing Cells."))
24 | (some #(when (= synapse-id (:synapse-id (deref %))) %)
25 | (c-synapses *depender*)))
26 |
27 | (defmacro with-synapse [[synapse-id [& closure-bindings]] & body]
28 | `(let [existing-syn# (existing-syn ~synapse-id)
29 | synapse# (or existing-syn#
30 |
31 | (let [new-syn#
32 | (let [~@closure-bindings]
33 | ;; (dp :making-syn!? (:prop @*depender*))
34 | (make-c-formula
35 | :model (:model @*depender*)
36 | :prop ~synapse-id
37 | :synapse-id ~synapse-id
38 | :code '~body
39 | :synaptic? true
40 | :rule (c-fn ~@body)))]
41 | ;;(dp :built-synapse!!!!!!!!!!!!!!!! ~synapse-id @new-syn#)
42 | (rmap-set! [:synapses *depender*]
43 | (conj (c-synapses *depender*) new-syn#))
44 | (record-dependency new-syn#) ;; needed?!!!!
45 | ;; (dp :made-syn!!!!!!!!!!!! @new-syn#)
46 | new-syn#))
47 |
48 | value# (tilton.mx.cell.integrity/with-integrity ()
49 | ;; (dp :with-syn-ensure-syn-value (nil? existing-syn#))
50 | (ensure-value-is-current synapse# :synapse *depender*))]
51 | ;;(dp :synapse-returns ~synapse-id :useds (doall (map c-prop (c-useds synapse#))))
52 | (record-dependency synapse#)
53 | value#))
54 |
55 | (defn call-with-synapse [synapse-id cell-factory]
56 | (let [existing-syn (existing-syn synapse-id)
57 | synapse (or existing-syn
58 | (let [new-syn (cell-factory)]
59 | (dp :building-synapse ~synapse-id)
60 | (rmap-set! [:synapses *depender*]
61 | (conj (c-synapses *depender*) new-syn))
62 | (record-dependency new-syn) ;; needed?!!!!
63 | new-syn))
64 |
65 | value (tilton.mx.cell.integrity/with-integrity ()
66 | (ensure-value-is-current synapse :synapse *depender*))]
67 | (record-dependency synapse)
68 |
69 | value))
70 |
71 | (defmacro cSyn [[synapse-id [& closure-bindings]] & body]
72 | `(call-with-synapse ~synapse-id #(let [~@closure-bindings]
73 | (make-c-formula
74 | :model (c-model *depender*)
75 | :prop ~synapse-id
76 | :synapse-id ~synapse-id
77 | :code '~body
78 | :synaptic? true
79 | :rule (c-fn ~@body)))))
--------------------------------------------------------------------------------
/src/tilton/mx/foundation.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.mx.foundation
2 | (:require [clojure.string :as str]))
3 |
4 | (defprotocol PObserver
5 | (observe [this prop me new-value prior-value cell]))
6 |
7 | (deftype MXImplementer [])
8 |
9 | ;; --- mx-common ----------------------
10 |
11 | (defn mx-type [it]
12 | (when-let [m (meta it)]
13 | (:mx-type m)))
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/tilton/test/family_kids.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.test.family-kids
2 | (:require
3 | [tilton.mx.foundation :refer [mx-type]]
4 | [tilton.mx.base
5 | :refer [trx dp dpx prog1 *trx?*]]
6 |
7 | [tilton.mx.cell.base
8 | :refer [without-c-dependency cells-init c-optimized-away? c-formula? c-value c-optimize
9 | c-unbound? c-input?
10 | c-model c-valid? c-useds
11 | c-state +pulse+ c-pulse-observed
12 | *call-stack* *defer-changes* unbound
13 | c-rule c-me c-value-state c-callers
14 | unlink-from-callers *causation*
15 | c-prop-name c-synaptic?
16 | c-pulse c-pulse-last-changed c-ephemeral? c-prop c-props
17 | c-lazy] :as cty]
18 | [tilton.mx.cell.integrity :refer [with-integrity]]
19 | [tilton.mx.cell.observer
20 | :refer [fn-obs]]
21 | [tilton.mx.cell.core
22 | :refer [cF cF+ c-reset-next! cFonce cFn
23 | cI cset! make-cell make-c-formula]]
24 | [tilton.mx.cell.evaluate :refer [cget]]
25 | [tilton.mx.model.peek :refer [mref? cref?]]
26 | [tilton.mx.model.base :refer [md-cz md-cell]]
27 | [tilton.mx.model.core
28 | :refer [the-kids mdv! fm! make mset! *md-quiesce-log?*]
29 | :as md]
30 | [tilton.mx.api :refer [dp dpx wmx-iso minfo mget mset! mupdate! mav muv
31 | navig fasc fm* cF cF+ cI cFonce ]]))
32 |
33 | (defn k-notq2be []
34 | (binding [*md-quiesce-log?* true]
35 | (let [f (md/make-family
36 | :ee (cI 2)
37 | :kids (cF (the-kids
38 | (when (odd? (mget me :ee))
39 | (md/make
40 | :name :yep
41 | :value (cF+ [:dbg :quiesce]
42 | (do
43 | (let [par (:parent @me)]
44 | (let [ee (mget par :ee)]
45 | (* 14 ee))))))))))]
46 | (assert (dart/is? (mx-type f) md/Family)
47 | (str "k-notq2be bad family"))
48 | (assert (empty? (mget f :kids)))
49 |
50 | (do
51 | (mset! f :ee 3)
52 | (assert (not (empty? (mget f :kids))))
53 | (assert (= 42 (mdv! :yep :value f)))
54 |
55 | (dp :ok-42!!)
56 | (let [dmw (first (mget f :kids))]
57 | (assert (mref? dmw))
58 | (dp :ok-42-2!!)
59 | (mset! f :ee 0)
60 | (dp :ok-42-3!!)
61 | (assert (empty? (mget f :kids)))
62 |
63 | ;; (dp :dmw @dmw :meta (meta dmw))
64 | ;; todo get kids observe to quiesce kids
65 |
66 | (assert (= :md-quiesced (:state (meta dmw)))))
67 | (dp :k-notq2be-exit)))))
68 |
69 | (defn run-tests []
70 | (k-notq2be)
71 | (dp :family-kids-OK))
72 |
73 |
74 |
--------------------------------------------------------------------------------
/src/tilton/test/observer.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.test.observer
2 | (:require
3 | [tilton.mx.base
4 | :refer [trx dp dpx prog1]]
5 |
6 | [tilton.mx.foundation :refer [mx-type]]
7 | [tilton.mx.model.peek :refer [minfo mref? minfo c-type cref? cinfo Cell CellFormula]]
8 | [tilton.mx.cell.base
9 | :refer [without-c-dependency c-optimized-away? c-formula? c-value c-optimize
10 | c-unbound? c-input?
11 | cells-init c-callers c-useds
12 | c-model c-valid? c-useds
13 | c-state +pulse+ c-pulse-observed
14 | *call-stack* *defer-changes*
15 | c-rule c-me c-value-state c-callers
16 | unlink-from-callers *causation*
17 | c-prop-name c-synaptic?
18 | c-pulse c-pulse-last-changed c-ephemeral? c-prop
19 | c-lazy] :as cty]
20 | [tilton.mx.cell.evaluate :refer [cget]]
21 | [tilton.mx.cell.observer :refer [fn-obs]]
22 |
23 | [tilton.mx.cell.core
24 | :refer [cF cF+ cI cset!]]
25 | [tilton.mx.model.peek :refer [mref?]]
26 | ))
27 |
28 | (defn t-formula []
29 | (cells-init)
30 | (let [bingo (atom false)
31 | c (cF+ [:prop :bingo
32 | :watch (fn-obs
33 | (reset! bingo true))]
34 | (+ 40 2))]
35 | (assert (dart/is? (c-type c) CellFormula))
36 | (assert (= (c-value-state c) :unbound))
37 | (assert (= #{} (c-callers c)))
38 | (assert (= #{} (c-useds c)))
39 | (assert (not (c-input? c)))
40 | (assert (not (c-valid? c)))
41 | (assert (nil? (c-model c)))
42 | (dp :cget-before (cget c) :deref (cinfo c))
43 | (assert (= (cget c) 42))
44 | (assert @bingo)
45 | ))
46 |
47 | (defn test-input []
48 | (let [bingo2 (atom 0)
49 | c (cI 42 :prop :bingo2
50 | :watch (fn-obs
51 | (dp :test-input-obs-runs!!!)
52 | (swap! bingo2 inc)))]
53 | (assert (dart/is? (c-type c) Cell))
54 | (assert (= (c-value-state c) :valid))
55 | (assert (= #{} (c-callers c)))
56 | (assert (c-input? c))
57 | (assert (c-valid? c))
58 | (assert (nil? (c-model c)))
59 | (assert (= :bingo2 (c-prop c) (c-prop-name c)))
60 | (assert (= (cget c) 42))
61 | (assert (= 1 @bingo2))
62 |
63 | (cset! c 54)
64 | (assert (= (cget c) 54))
65 | (assert (= 2 @bingo2))))
66 |
67 | (defn t-custom-obs []
68 | (let [bobs (atom nil)
69 | b (cI 2 :prop :bb
70 | :watch (fn-obs
71 | (dp :watch-b prop me new old)
72 | (reset! bobs new)))
73 | cobs (atom nil)
74 | c (cF+ [:watch (fn-obs [prop me new old c]
75 | (trx prop me new old)
76 | (reset! cobs new))]
77 | (* 10 (cget b)))]
78 | (do
79 | (dp :MX-built!------------------)
80 | (assert (= @bobs nil) (str "@bobs not nil: " @bobs))
81 | (assert (= (cget b) 2))
82 | (assert (= @bobs 2) (str "@bobs not nil: " @bobs))
83 | (assert (= (cget c) 20))
84 | (assert (= @cobs 20))
85 | (cset! b 3)
86 | (assert (= 3 @bobs))
87 | (assert (= 30 (cget c)))
88 | (assert (= 30 @cobs)))))
89 |
90 | (defn run-tests []
91 | (t-formula)
92 | (test-input)
93 | (t-custom-obs)
94 | (dp :observer-tests-OK))
95 |
96 |
97 |
--------------------------------------------------------------------------------
/src/tilton/testing.cljd:
--------------------------------------------------------------------------------
1 | (ns tilton.testing
2 | (:require
3 | [tilton.mx.base :refer [dp]]
4 | [tilton.test.cell-core :refer [run-tests] :as test-cell-core]
5 | [tilton.test.hello-cells :refer [run-tests] :as hello-cells]
6 | [tilton.test.evaluate :refer [run-tests] :as test-eval]
7 | [tilton.test.observer :refer [run-tests] :as test-obs]
8 | [tilton.test.integrity :refer [run-tests] :as test-integ]
9 | [tilton.test.lazy-cells :refer [run-tests] :as test-lazy]
10 | ;[tilton.test.synapse :refer [run-tests] :as test-syn]
11 | [tilton.test.model-core :refer [run-tests] :as md]
12 | [tilton.test.family-kids :refer [run-tests] :as fm-kids]))
13 |
14 | (defn run-test-lazy []
15 | (test-lazy/run-tests)
16 | (dp :test-lzy-ok))
17 |
18 | (defn run-tests []
19 | (dp :----------------------start-tests)
20 | (do (test-cell-core/run-tests)
21 | (dp :------------------cell-core-ok))
22 | (hello-cells/run-tests)
23 | (dp :----------------------hello-cells-ok)
24 | (test-eval/run-tests)
25 | (dp :--------------------eval-ok)
26 | (test-obs/run-tests)
27 | (dp :----------------obs-watch-ok)
28 | (test-integ/run-tests)
29 | (dp :----------------------integ-ok)
30 | (test-lazy/run-tests)
31 | (dp :---------------------------lazy-ok)
32 | (md/run-tests)
33 | (dp :--------------------------md-ok)
34 | (fm-kids/run-tests)
35 | (dp :----------------------------------fm-kids-ok)
36 | ; TODO synapses (test-syn/run-tests)
37 | (hello-cells/run-tests)
38 | (dp "-------------------------testing-OK"))
39 |
40 |
--------------------------------------------------------------------------------
/sup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | clj -M:cljd flutter --dart-define=SUPA_MVX_URL=$SUPA_MVX_URL \
4 | --dart-define=SUPA_MVX_KEY=$SUPA_MVX_KEY
5 |
--------------------------------------------------------------------------------
/sup_macos.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | clj -M:cljd flutter -d macos \
4 | --dart-define=SUPA_MVX_URL=$SUPA_MVX_URL \
5 | --dart-define=SUPA_MVX_KEY=$SUPA_MVX_KEY
6 |
--------------------------------------------------------------------------------
/supmvx.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | clj -M:cljd flutter --dart-define=SUPA_MVX_URL=$SUPA_MVX_URL \
4 | --dart-define=SUPA_MVX_KEY=$SUPA_MVX_KEY
5 |
--------------------------------------------------------------------------------
/supweb.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | clj -M:cljd flutter -d chrome \
4 | --dart-define=SUPA_MVX_URL=$SUPA_MVX_URL \
5 | --dart-define=SUPA_MVX_KEY=$SUPA_MVX_KEY
6 |
--------------------------------------------------------------------------------
/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/web/favicon.png
--------------------------------------------------------------------------------
/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/web/icons/Icon-maskable-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/web/icons/Icon-maskable-512.png
--------------------------------------------------------------------------------
/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "matrix",
3 | "short_name": "matrix",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | },
22 | {
23 | "src": "icons/Icon-maskable-192.png",
24 | "sizes": "192x192",
25 | "type": "image/png",
26 | "purpose": "maskable"
27 | },
28 | {
29 | "src": "icons/Icon-maskable-512.png",
30 | "sizes": "512x512",
31 | "type": "image/png",
32 | "purpose": "maskable"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/windows/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral/
2 |
3 | # Visual Studio user-specific files.
4 | *.suo
5 | *.user
6 | *.userosscache
7 | *.sln.docstates
8 |
9 | # Visual Studio build-related files.
10 | x64/
11 | x86/
12 |
13 | # Visual Studio cache files
14 | # files ending in .cache can be ignored
15 | *.[Cc]ache
16 | # but keep track of directories ending in .cache
17 | !*.[Cc]ache/
18 |
--------------------------------------------------------------------------------
/windows/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #include "generated_plugin_registrant.h"
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | void RegisterPlugins(flutter::PluginRegistry* registry) {
14 | AppLinksPluginCApiRegisterWithRegistrar(
15 | registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
16 | FlutterTtsPluginRegisterWithRegistrar(
17 | registry->GetRegistrarForPlugin("FlutterTtsPlugin"));
18 | UrlLauncherWindowsRegisterWithRegistrar(
19 | registry->GetRegistrarForPlugin("UrlLauncherWindows"));
20 | }
21 |
--------------------------------------------------------------------------------
/windows/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #ifndef GENERATED_PLUGIN_REGISTRANT_
8 | #define GENERATED_PLUGIN_REGISTRANT_
9 |
10 | #include
11 |
12 | // Registers Flutter plugins.
13 | void RegisterPlugins(flutter::PluginRegistry* registry);
14 |
15 | #endif // GENERATED_PLUGIN_REGISTRANT_
16 |
--------------------------------------------------------------------------------
/windows/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | app_links
7 | flutter_tts
8 | url_launcher_windows
9 | )
10 |
11 | list(APPEND FLUTTER_FFI_PLUGIN_LIST
12 | )
13 |
14 | set(PLUGIN_BUNDLED_LIBRARIES)
15 |
16 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
17 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
18 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
19 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
20 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
21 | endforeach(plugin)
22 |
23 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
24 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
25 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
26 | endforeach(ffi_plugin)
27 |
--------------------------------------------------------------------------------
/windows/runner/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.14)
2 | project(runner LANGUAGES CXX)
3 |
4 | add_executable(${BINARY_NAME} WIN32
5 | "flutter_window.cpp"
6 | "main.cpp"
7 | "utils.cpp"
8 | "win32_window.cpp"
9 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
10 | "Runner.rc"
11 | "runner.exe.manifest"
12 | )
13 | apply_standard_settings(${BINARY_NAME})
14 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
15 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
16 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
17 | add_dependencies(${BINARY_NAME} flutter_assemble)
18 |
--------------------------------------------------------------------------------
/windows/runner/Runner.rc:
--------------------------------------------------------------------------------
1 | // Microsoft Visual C++ generated resource script.
2 | //
3 | #pragma code_page(65001)
4 | #include "resource.h"
5 |
6 | #define APSTUDIO_READONLY_SYMBOLS
7 | /////////////////////////////////////////////////////////////////////////////
8 | //
9 | // Generated from the TEXTINCLUDE 2 resource.
10 | //
11 | #include "winres.h"
12 |
13 | /////////////////////////////////////////////////////////////////////////////
14 | #undef APSTUDIO_READONLY_SYMBOLS
15 |
16 | /////////////////////////////////////////////////////////////////////////////
17 | // English (United States) resources
18 |
19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
21 |
22 | #ifdef APSTUDIO_INVOKED
23 | /////////////////////////////////////////////////////////////////////////////
24 | //
25 | // TEXTINCLUDE
26 | //
27 |
28 | 1 TEXTINCLUDE
29 | BEGIN
30 | "resource.h\0"
31 | END
32 |
33 | 2 TEXTINCLUDE
34 | BEGIN
35 | "#include ""winres.h""\r\n"
36 | "\0"
37 | END
38 |
39 | 3 TEXTINCLUDE
40 | BEGIN
41 | "\r\n"
42 | "\0"
43 | END
44 |
45 | #endif // APSTUDIO_INVOKED
46 |
47 |
48 | /////////////////////////////////////////////////////////////////////////////
49 | //
50 | // Icon
51 | //
52 |
53 | // Icon with lowest ID value placed first to ensure application icon
54 | // remains consistent on all systems.
55 | IDI_APP_ICON ICON "resources\\app_icon.ico"
56 |
57 |
58 | /////////////////////////////////////////////////////////////////////////////
59 | //
60 | // Version
61 | //
62 |
63 | #ifdef FLUTTER_BUILD_NUMBER
64 | #define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
65 | #else
66 | #define VERSION_AS_NUMBER 1,0,0
67 | #endif
68 |
69 | #ifdef FLUTTER_BUILD_NAME
70 | #define VERSION_AS_STRING #FLUTTER_BUILD_NAME
71 | #else
72 | #define VERSION_AS_STRING "1.0.0"
73 | #endif
74 |
75 | VS_VERSION_INFO VERSIONINFO
76 | FILEVERSION VERSION_AS_NUMBER
77 | PRODUCTVERSION VERSION_AS_NUMBER
78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
79 | #ifdef _DEBUG
80 | FILEFLAGS VS_FF_DEBUG
81 | #else
82 | FILEFLAGS 0x0L
83 | #endif
84 | FILEOS VOS__WINDOWS32
85 | FILETYPE VFT_APP
86 | FILESUBTYPE 0x0L
87 | BEGIN
88 | BLOCK "StringFileInfo"
89 | BEGIN
90 | BLOCK "040904e4"
91 | BEGIN
92 | VALUE "CompanyName", "com.example" "\0"
93 | VALUE "FileDescription", "matrix" "\0"
94 | VALUE "FileVersion", VERSION_AS_STRING "\0"
95 | VALUE "InternalName", "matrix" "\0"
96 | VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0"
97 | VALUE "OriginalFilename", "matrix.exe" "\0"
98 | VALUE "ProductName", "matrix" "\0"
99 | VALUE "ProductVersion", VERSION_AS_STRING "\0"
100 | END
101 | END
102 | BLOCK "VarFileInfo"
103 | BEGIN
104 | VALUE "Translation", 0x409, 1252
105 | END
106 | END
107 |
108 | #endif // English (United States) resources
109 | /////////////////////////////////////////////////////////////////////////////
110 |
111 |
112 |
113 | #ifndef APSTUDIO_INVOKED
114 | /////////////////////////////////////////////////////////////////////////////
115 | //
116 | // Generated from the TEXTINCLUDE 3 resource.
117 | //
118 |
119 |
120 | /////////////////////////////////////////////////////////////////////////////
121 | #endif // not APSTUDIO_INVOKED
122 |
--------------------------------------------------------------------------------
/windows/runner/flutter_window.cpp:
--------------------------------------------------------------------------------
1 | #include "flutter_window.h"
2 |
3 | #include
4 |
5 | #include "flutter/generated_plugin_registrant.h"
6 |
7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project)
8 | : project_(project) {}
9 |
10 | FlutterWindow::~FlutterWindow() {}
11 |
12 | bool FlutterWindow::OnCreate() {
13 | if (!Win32Window::OnCreate()) {
14 | return false;
15 | }
16 |
17 | RECT frame = GetClientArea();
18 |
19 | // The size here must match the window dimensions to avoid unnecessary surface
20 | // creation / destruction in the startup path.
21 | flutter_controller_ = std::make_unique(
22 | frame.right - frame.left, frame.bottom - frame.top, project_);
23 | // Ensure that basic setup of the controller was successful.
24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) {
25 | return false;
26 | }
27 | RegisterPlugins(flutter_controller_->engine());
28 | SetChildContent(flutter_controller_->view()->GetNativeWindow());
29 | return true;
30 | }
31 |
32 | void FlutterWindow::OnDestroy() {
33 | if (flutter_controller_) {
34 | flutter_controller_ = nullptr;
35 | }
36 |
37 | Win32Window::OnDestroy();
38 | }
39 |
40 | LRESULT
41 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
42 | WPARAM const wparam,
43 | LPARAM const lparam) noexcept {
44 | // Give Flutter, including plugins, an opportunity to handle window messages.
45 | if (flutter_controller_) {
46 | std::optional result =
47 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
48 | lparam);
49 | if (result) {
50 | return *result;
51 | }
52 | }
53 |
54 | switch (message) {
55 | case WM_FONTCHANGE:
56 | flutter_controller_->engine()->ReloadSystemFonts();
57 | break;
58 | }
59 |
60 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
61 | }
62 |
--------------------------------------------------------------------------------
/windows/runner/flutter_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_FLUTTER_WINDOW_H_
2 | #define RUNNER_FLUTTER_WINDOW_H_
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | #include "win32_window.h"
10 |
11 | // A window that does nothing but host a Flutter view.
12 | class FlutterWindow : public Win32Window {
13 | public:
14 | // Creates a new FlutterWindow hosting a Flutter view running |project|.
15 | explicit FlutterWindow(const flutter::DartProject& project);
16 | virtual ~FlutterWindow();
17 |
18 | protected:
19 | // Win32Window:
20 | bool OnCreate() override;
21 | void OnDestroy() override;
22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
23 | LPARAM const lparam) noexcept override;
24 |
25 | private:
26 | // The project to run.
27 | flutter::DartProject project_;
28 |
29 | // The Flutter instance hosted by this window.
30 | std::unique_ptr flutter_controller_;
31 | };
32 |
33 | #endif // RUNNER_FLUTTER_WINDOW_H_
34 |
--------------------------------------------------------------------------------
/windows/runner/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "flutter_window.h"
6 | #include "utils.h"
7 |
8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
9 | _In_ wchar_t *command_line, _In_ int show_command) {
10 | // Attach to console when present (e.g., 'flutter run') or create a
11 | // new console when running with a debugger.
12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
13 | CreateAndAttachConsole();
14 | }
15 |
16 | // Initialize COM, so that it is available for use in the library and/or
17 | // plugins.
18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
19 |
20 | flutter::DartProject project(L"data");
21 |
22 | std::vector command_line_arguments =
23 | GetCommandLineArguments();
24 |
25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
26 |
27 | FlutterWindow window(project);
28 | Win32Window::Point origin(10, 10);
29 | Win32Window::Size size(1280, 720);
30 | if (!window.CreateAndShow(L"matrix", origin, size)) {
31 | return EXIT_FAILURE;
32 | }
33 | window.SetQuitOnClose(true);
34 |
35 | ::MSG msg;
36 | while (::GetMessage(&msg, nullptr, 0, 0)) {
37 | ::TranslateMessage(&msg);
38 | ::DispatchMessage(&msg);
39 | }
40 |
41 | ::CoUninitialize();
42 | return EXIT_SUCCESS;
43 | }
44 |
--------------------------------------------------------------------------------
/windows/runner/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Runner.rc
4 | //
5 | #define IDI_APP_ICON 101
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NEXT_RESOURCE_VALUE 102
12 | #define _APS_NEXT_COMMAND_VALUE 40001
13 | #define _APS_NEXT_CONTROL_VALUE 1001
14 | #define _APS_NEXT_SYMED_VALUE 101
15 | #endif
16 | #endif
17 |
--------------------------------------------------------------------------------
/windows/runner/resources/app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kennytilton/flutter-mx/c177b2eec9af462cb8fea3f8ae0b1f255e267105/windows/runner/resources/app_icon.ico
--------------------------------------------------------------------------------
/windows/runner/runner.exe.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PerMonitorV2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/windows/runner/utils.cpp:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | void CreateAndAttachConsole() {
11 | if (::AllocConsole()) {
12 | FILE *unused;
13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
14 | _dup2(_fileno(stdout), 1);
15 | }
16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
17 | _dup2(_fileno(stdout), 2);
18 | }
19 | std::ios::sync_with_stdio();
20 | FlutterDesktopResyncOutputStreams();
21 | }
22 | }
23 |
24 | std::vector GetCommandLineArguments() {
25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
26 | int argc;
27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
28 | if (argv == nullptr) {
29 | return std::vector();
30 | }
31 |
32 | std::vector command_line_arguments;
33 |
34 | // Skip the first argument as it's the binary name.
35 | for (int i = 1; i < argc; i++) {
36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
37 | }
38 |
39 | ::LocalFree(argv);
40 |
41 | return command_line_arguments;
42 | }
43 |
44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
45 | if (utf16_string == nullptr) {
46 | return std::string();
47 | }
48 | int target_length = ::WideCharToMultiByte(
49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
50 | -1, nullptr, 0, nullptr, nullptr);
51 | if (target_length == 0) {
52 | return std::string();
53 | }
54 | std::string utf8_string;
55 | utf8_string.resize(target_length);
56 | int converted_length = ::WideCharToMultiByte(
57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
58 | -1, utf8_string.data(),
59 | target_length, nullptr, nullptr);
60 | if (converted_length == 0) {
61 | return std::string();
62 | }
63 | return utf8_string;
64 | }
65 |
--------------------------------------------------------------------------------
/windows/runner/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_UTILS_H_
2 | #define RUNNER_UTILS_H_
3 |
4 | #include
5 | #include
6 |
7 | // Creates a console for the process, and redirects stdout and stderr to
8 | // it for both the runner and the Flutter library.
9 | void CreateAndAttachConsole();
10 |
11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
12 | // encoded in UTF-8. Returns an empty std::string on failure.
13 | std::string Utf8FromUtf16(const wchar_t* utf16_string);
14 |
15 | // Gets the command line arguments passed in as a std::vector,
16 | // encoded in UTF-8. Returns an empty std::vector on failure.
17 | std::vector GetCommandLineArguments();
18 |
19 | #endif // RUNNER_UTILS_H_
20 |
--------------------------------------------------------------------------------
/windows/runner/win32_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_WIN32_WINDOW_H_
2 | #define RUNNER_WIN32_WINDOW_H_
3 |
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be
11 | // inherited from by classes that wish to specialize with custom
12 | // rendering and input handling
13 | class Win32Window {
14 | public:
15 | struct Point {
16 | unsigned int x;
17 | unsigned int y;
18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {}
19 | };
20 |
21 | struct Size {
22 | unsigned int width;
23 | unsigned int height;
24 | Size(unsigned int width, unsigned int height)
25 | : width(width), height(height) {}
26 | };
27 |
28 | Win32Window();
29 | virtual ~Win32Window();
30 |
31 | // Creates and shows a win32 window with |title| and position and size using
32 | // |origin| and |size|. New windows are created on the default monitor. Window
33 | // sizes are specified to the OS in physical pixels, hence to ensure a
34 | // consistent size to will treat the width height passed in to this function
35 | // as logical pixels and scale to appropriate for the default monitor. Returns
36 | // true if the window was created successfully.
37 | bool CreateAndShow(const std::wstring& title,
38 | const Point& origin,
39 | const Size& size);
40 |
41 | // Release OS resources associated with window.
42 | void Destroy();
43 |
44 | // Inserts |content| into the window tree.
45 | void SetChildContent(HWND content);
46 |
47 | // Returns the backing Window handle to enable clients to set icon and other
48 | // window properties. Returns nullptr if the window has been destroyed.
49 | HWND GetHandle();
50 |
51 | // If true, closing this window will quit the application.
52 | void SetQuitOnClose(bool quit_on_close);
53 |
54 | // Return a RECT representing the bounds of the current client area.
55 | RECT GetClientArea();
56 |
57 | protected:
58 | // Processes and route salient window messages for mouse handling,
59 | // size change and DPI. Delegates handling of these to member overloads that
60 | // inheriting classes can handle.
61 | virtual LRESULT MessageHandler(HWND window,
62 | UINT const message,
63 | WPARAM const wparam,
64 | LPARAM const lparam) noexcept;
65 |
66 | // Called when CreateAndShow is called, allowing subclass window-related
67 | // setup. Subclasses should return false if setup fails.
68 | virtual bool OnCreate();
69 |
70 | // Called when Destroy is called.
71 | virtual void OnDestroy();
72 |
73 | private:
74 | friend class WindowClassRegistrar;
75 |
76 | // OS callback called by message pump. Handles the WM_NCCREATE message which
77 | // is passed when the non-client area is being created and enables automatic
78 | // non-client DPI scaling so that the non-client area automatically
79 | // responsponds to changes in DPI. All other messages are handled by
80 | // MessageHandler.
81 | static LRESULT CALLBACK WndProc(HWND const window,
82 | UINT const message,
83 | WPARAM const wparam,
84 | LPARAM const lparam) noexcept;
85 |
86 | // Retrieves a class instance pointer for |window|
87 | static Win32Window* GetThisFromHandle(HWND const window) noexcept;
88 |
89 | bool quit_on_close_ = false;
90 |
91 | // window handle for top level window.
92 | HWND window_handle_ = nullptr;
93 |
94 | // window handle for hosted content.
95 | HWND child_content_ = nullptr;
96 | };
97 |
98 | #endif // RUNNER_WIN32_WINDOW_H_
99 |
--------------------------------------------------------------------------------